JS 中用字面语法设置对象属性时的“反直觉”行为
2015-03-07 Tech
myObjectfoo = 233
服用《You Don't Know JS this and Object Prototypes》后,现在看到这句是再也不敢认为结果一定是 myObject 上有了一个名为 foo,值为 233 的属性了。
具体执行的结果还要看具体情形来决定。
如果 myObject 已经有一个名为 foo 的普通的属性了,那么执行的结果就是给 myObject 现有的 foo 属性进行了一次赋值。
然而 myObject 上面找不到 foo,那就和访问一个对象本身不存在的属性一样,JS 会一级一级地扒 myObject 的原型链最终确定 foo 的存在情况,从而来决定执行结果。
-
如果原型链上也没有
foo,那么就直接在myObject上添加一个foo属性并赋值。 -
原型链上找到了
foo,并且它是可写的(writable:true),那么也是直接在myObject上添加一个foo属性并赋值,从而原型链上的foo被遮盖了。 -
原型链上找到了
foo,但它是只读的(writable:false),那什么都不会发生,myObject上不会多一个foo属性,原型链上的那只foo也不会改变;如果你处在严格模式的话,JS 会顺便给你抛一个错误。 -
原型链上找到了名为
foo的Setter,这个时候始终会调用找到的那个Setter,myObject上不会创建新属性,Setter也不会被重新赋值。
还是来看直观的代码吧 ╮( ̄ ▽  ̄)╭
var Shoujo = Objectvar A = ObjectAmagicType = 'dark'/*全新的属性,直接添加到原来的对象身上Shoujo -> { hairColor: "black", isReachable: false, makeUpCode: undefined }A -> { magicType: "dark" }*/AhairColor = 'silver'/*原型链上既有的普通属性,也是直接添加到原来的对象身上Shoujo -> { hairColor: "black", isReachable: false, makeUpCode: undefined }A -> { magicType: "dark", hairColor: "silver" }*/AisReachable = true/*原型链上既有的只读属性,什么都没有发生 ˊ_>ˋShoujo -> { hairColor: "black", isReachable: false, makeUpCode: undefined }A -> { magicType: "dark", hairColor: "silver" }*/AmakeUpCode = 'I am the bone of my...'//"I am the bone of my... Henshin !"/*原型链上既有的 Setter,调用 SetterShoujo -> { hairColor: "black", isReachable: false, makeUpCode: undefined }A -> { magicType: "dark", hairColor: "silver" }*/
另外,['propertyName'] 这种语法和 .propertyName 一样也遵循上面的行为。
当然,这些行为不会影响你使用 Object.defineProperty() 和 Object.defineProperties() 来设置对象的属性。
Comments...