美文网首页
原型之对象属性的设置与屏蔽

原型之对象属性的设置与屏蔽

作者: BIGHAI | 来源:发表于2017-05-28 16:35 被阅读0次

    我们现在考虑这么一种情况,假设有一个对象obj,我们要对其进行动态增加一个属性a,但是对象obj的[[Prototype]]原型链上面有属性a,那么我们为对象obj动态添加属性a是否一定会发生屏蔽现象呢?(即动态添加完之后,对象自身的a属性覆盖了原型链上的属性a)

    对于上面这个问题,相信大部分人都会回答会屏蔽掉。然而事实并非如此,涉及到这种情况时的屏蔽问题会变得更加复杂。下面详细分析一下JavaScript对此做出的响应会有哪些:

    • 1.如果在[[Prototype]]原型链上的那个同名属性的属性描述符writable被设置为true的话,那么就会直接在obj上动态添加这个属性。此时,会发生屏蔽工作。
    Object.defineProperty(Object.prototype, "a", {
      "value": "protoValue",
      "writable": true,
      "enumerable": true,
      "configurable": true
    })
    var obj = {"b": 2}
    console.log(obj.a)//"protoValue"
    obj.a = "selfValue"
    console.log(obj.a)//"selfValue"
    
    • 2.如果在[[Prototype]]原型链上的那个同名属性的属性描述符writable被设置为false的话,那么在obj上动态增加这个属性将没有效果,不会发生屏蔽工作。在严格模式下,这样做会报错。
    //"use strict";加上这句后报错
    Object.defineProperty(Object.prototype, "a", {
      "value": "protoValue",
      "writable": false,
      "enumerable": true,
      "configurable": true
    })
    var obj = {"b": 2}
    console.log(obj.b)//protoValue
    obj.a = "selfValue"
    console.log(obj.a)//protoValue
    

    1.隐式屏蔽

    有些情况下会发生隐式屏蔽,这个时候真的让人猝不及防,一不留神就造成了个错误。看下面这个例子:

    var source_object = {"a": 2}
    var target_object = Object.create(source_object)
    console.log(source_object.a)//2
    console.log(target_object.a)//2
    source_object.hasOwnProperty("a")//true
    target_object.hasOwnProperty("a")//false
    target_object.a++//隐式屏蔽
    source_object.a//2
    target_object.a++//3
    target_object.hasOwnProperty("a")//true
    

    分析:可以这样理解target_object.a = target_object.a + 1;由于[[Prototype]]原型链上的a属性的属性描述符writable的值时true,所以此时发生了屏蔽现象。

    END

    相关文章

      网友评论

          本文标题:原型之对象属性的设置与屏蔽

          本文链接:https://www.haomeiwen.com/subject/pxrhfxtx.html