《你不知道的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)
};
}
};
}
} );