原型链的小坑-属性屏蔽
javascript的原型是面试必会问到的知识点,
当一个对象被创建出来的时候,就会被赋予一个非空的对象作为[[prototype]]
原型链的终点是Object.prototype
- 当我们执行如下代码的时候,我们创建了一个b对象并且以pro为原型,
按照原型链的规则,当我们调用b.a时,在b中并没有a这个属性所以会查找他的原型链,
在他的原型链中找到了这个属性,所以正常访问,当b中有这个属性的时候,就会访问本对象
的a属性而对他的原型中的同名属性进行了屏蔽
const pro = {
a: 12
}
const b = Object.create(pro)
console.log(b.a)
b.a = 13
console.log(pro.a, b.a)
- 当我们以Object.defineProperty来把原型对象的属性定义成writable:false
那么就会发生我们无法在obj对象上定义原型的同名属性。在严格模式下会报错,非严格模式下会静默的失败
'use strict'
const pro = Object.defineProperty({}, 'a', {
value: 1,
writable: false
})
const obj = Object.create(pro)
console.log(obj.a) // 1
obj.a = 3 // TypeError: Cannot assign to read only property 'a' of object '#<Object>'
- 当原型的属性是一个setter时, 并没有发生属性屏蔽现象,而只是触发了原型的setter方法
const pro = {
set a(v) {
console.log(v, '触发了pro的setter')
}
}
const obj = Object.create(pro)
obj.a = 1 // 1 '触发了pro的setter'
console.log(Object.hasOwnProperty.call(obj, 'a')) //false
那么当我们如此使用的时候会发生什么呢?
const pro = {
a: 1
}
const obj = Object.create(pro)
obj.a++
console.log(pro.a) // ??????
console.log(obj.a) // ??????