js进阶学习

167 阅读2分钟

《你不知道的js上》

new创建对象

通过new创建对象时,如果构造函数有返回且为对象(数组和其他引用类型也是对象),则拿到的对象是构造函数返回的对象,而不是通过new创建的对象

this指向优先级

new > 显式call/apply/bind > 隐式a.b() > 默认b()

箭头函数的作用

箭头函数的出现让this的指向不再琢磨不定,符合js的词法作用域而不是动态作用域

字符串为什么有方法

字符串可以使用如toString之类的方法,是因为引擎会自动把字面量转换成String对象,数值类型也是一样

属性访问和键访问的区别

- . 操作符要求属性名满足标识符的命名规范
- [".."] 语法可以接受任意 UTF-8/Unicode 字符串作为属性名,如"SuperFun!"
- [".."] 语法可以接受变量或表达式,并将结果自动转为字符串

属性设置

- 把 configurable 修改成false 是单向操作,无法撤销,但即便属性是 configurable:false,我们还是可以把 writable 的状态由true 改为 false,但是无法由 false 改为 true
- 禁止扩展Object.preventExtensions(obj),不允许添加新属性
- 密封Object.seal(obj),禁止扩展并把所有现有属性标记为 configurable:false
- 冻结Object.freeze(obj),密封并把所有“数据访问”属性标记为 writable:false

属性检查

- 有没有:in 操作符会检查属性是否在对象及其 [[Prototype]] 原型链中,而hasOwnProperty(..) 只会检查属性是否在 myObject 对象中,不会检查 [[Prototype]] 链。
- Object.keys(..) 会返回一个数组,包含所有可枚举属性,Object.getOwnPropertyNames(..)会返回一个数组,包含所有属性,无论它们是否可枚举。二者都只会查找对象直接包含的属性

迭代器

- 数组内置有迭代器,通过arr[Symbol.iterator]()获取迭代器对象@@iterator对象,调用next()方法可依次获取值,如{ value:1, done:false }
- for..of 循环首先会向被访问对象请求一个迭代器对象,然后通过调用迭代器对象的next() 方法来遍历所有返回值
- 对象没有内置的迭代器,所以obj[Symbol.iterator]返回undefined,当然也可以自定义添加,之后就可以使用for..of
Object.defineProperty( myObject, Symbol.iterator, {
  enumerable: false, // 设置为不可枚举
  writable: false,
  configurable: true,
  value: function() {
    var o = this;
    var idx = 0;
    var ks = Object.keys( o );
    return {
      next: function() {
      return {
        value: o[ks[idx++]],
        done: (idx > ks.length)
        };
      }
    };
  }
} );