js学习笔记-原型
[[prototype]]
js中的对象都有一个内置的 [[Prototype]]
属性,其实就是对于其他对象的引用。
在访问对象属性,触发 [[Get]]
操作的时候,先在对象本身查找是否有这个属性,没有的话就顺着 [[Prototype]]
原型链查找下去,访问到顶端还没有的话返回undefined。
for…in遍历对象(可枚举的对象)的原理也是这样的
所有 [[Prototype]]
链最终指向Object.prototype
属性的设置和屏蔽
|
|
这个语句在不同场景下有不同的操作:
myObj对象中有foo这个属性
此时的操作就是在修改已有的属性
myObj对象中没有foo这个属性,并且原型链上也没有这个属性
此时的操作,先遍历了myObj的原型链,类似于[[Get]]操作
没有找到对应的属性,于是foo属性会被添加到myObj上
foo属性既存在在myObj对象中,又出现在它的原型链上
此时的操作会发生屏蔽,对象中的foo属性会屏蔽原型链上所有foo属性
因为在获取的时候,总是会获取最底层的属性
myObj对象中没有foo这个属性,但是原型链上有这个属性
原型链上的foo属性是可访问可修改的
此时操作会发生屏蔽,直接在myObj对象上添加foo属性
原型链上的foo属性被标记为只读(writable:false)
此时无法修改原型链上已有属性,也无法在对象上创建foo(不会发生屏蔽)
在严格模式下会报错,非严格模式下赋值语句将被忽略
原型链上的foo是个setter
此时一定会调用这个setter,不会发生屏蔽,也不会重新定义foo这个setter
12*注:setter会覆盖单个属性默认的[[PUT]]操作如果药第二第三种情况也发生屏蔽,需要使用Object.defineProperty(...),而不是=赋值操作