你不知道的JS系列上( 48 ) - 对象属性设置和屏蔽
哪里是 [[Prototype]] 的尽头呢?所有普通的 [[Prototype]] 链最终都会指向内置的 Object.prototype。它包含了 JS 许多通用的功能,比如 .toString() .valueOf() .hasOwnProperty() .isPrototypeOf()
给一个对象设置属性并不仅仅是添加一个新属性或者修改已有的属性值。比如
myObject.foo = 'bar';
如果 foo 直接已经存在 myObject 中,这条赋值语句只会修改已有的属性值。
如果 foo 既出现在 myObject 中,又存在原型链上层,那会发生屏蔽, myObject 中包含的 foo 属性会屏蔽原型链上层的所有 foo 属性
如果 foo 不是直接存在于 myObject 中,[[Prototype]] 链就会被遍历,如果 foo 存在于原型链上层,接下来就有一系列行为
1、如果在原型链上层的 foo 的普通访问属性 writable: true。那么会直接在 myObject 中添加一个名为 foo 的新属性。它是屏蔽属性
2、如果在原型链上层的 foo 的普通访问属性 writable: false。那么无法修改已有属性或者在 myObject 上创建属性,严格模式下会报错
3、如果原型链上 foo 是一个 setter,那就一定会调用这个 setter,foo 不会被添加到 myObject,也不会重新定义 foo
如果希望在第二种和第三种情况也屏蔽 foo,那就不能使用 = 操作符来赋值,而是使用 Object.defineProperty(...) 来向 myObject 添加 foo