属性的设置过程
myObject.foo = "bar";
就这么一句简单的赋值过程,会经历什么呢?
来自《你不知道的Javascript》上第五章;
第一种情况:
myObject对象中包含foo属性,那么这种最简单,只会对foo属性的值进行修改;
第二种情况:
foo属性并不直接存在于myObject对象中,这时候就会对原型链[[Prototype]]进行遍历,类似[[get]]操作;如果原型链上找不到foo属性,那么就会在myObject对象上直接添加foo属性;
第三种情况:
foo属性不仅在myObject对象中,还存在于原型链上层;这时候会发生屏蔽;myObject.foo会优先选择原型链最底层的foo属性;
WOW,我的天,原来屏蔽有这么多道道;
第四种情况:
foo属性并不直接存在于myObject对象中,而是存在于原型链的上层
-
如果foo属性存在于原型链的上层,且该属性不是只读属性(writable:false),这时候就会将foo属性添加到myObject对象中,foo属性就是第三种情况的屏蔽属性;
let topobj = {foo: 'topFoo'} let myobj = Object.create(topobj) console.log(myobj) myobj.foo = 'myFoo' -
但是foo属性存在于原型链的上层,但是它是只读的属性,那么无法修改已有属性或者在myobj对象上创建屏蔽属性;
let topObj = {} Object.defineProperty(topObj, "foo", { value: 'topFoo', writable: false }) let myObj = Object.create(topObj) console.log("myObj before:", myObj) myObj.foo = 'myFoo' console.log("myObj after:", myObj)从输出结果可以看到赋值被忽略了:
严格模式下,当对foo属性赋值时,直接报错:
- 如果在 [[Prototype]] 链上层存在 foo 并且它是一个 setter(参见第 3 章),那就一定会调用这个 setter。foo 不会被添加到(或者说屏蔽于)myObject,也不会重新定义 foo 这个 setter。
对于这种情况,我没有特别理解,下面是我写的代码:和输出结果,不知道是不是我写的有问题🤨;各位友友如果有见解,希望评论里指正;
let topObj = {}
let foovalue = 'topFoo'
Object.defineProperty(topObj, "foo", {
get() {
return foovalue;
},
set(value) {
foovalue = value
console.log('seting', value);
}
})
let myObj = Object.create(topObj)
console.log("myObj before:", myObj)
myObj.foo = 'myFoo'
console.log("myObj after:", myObj)
输出结果: