search

Home  >  Q&A  >  body text

javascript给对象创建属性时查找原型链

js在给对象写属性时是不查找原型链的,只有读取是才会查找原型链,但是下面这种情况怎么解释呢?

        var obj = {};
        Object.defineProperty(obj,'x',{
            value: 1,
            writable: false,
            configurable: false,
            enumerable: false
        });
        var obj1 = Object.create(obj);
        obj1.x = 10;
        console.log(obj1.x);   // 仍然是1,这样是不是说查找了原型链了呢
PHP中文网PHP中文网2818 days ago364

reply all(2)I'll reply

  • PHP中文网

    PHP中文网2017-04-10 16:12:08

    比如说myObject.foo = "bar",这里分为以下的几种情况:
    如果myObject对象中包含名为foo的普通数据访问属性,那么修改已有的属性值;
    如果foo不存在于myObject对象中,它的原型链就会被遍历,如果原型链中没有foo属性,那么foo属性被添加到myObject对象里;
    如果foo属性存在于原型链中,那么又会分为三种情况:
    a:原型链中存在foo属性,但没有被标记为只读(writable:true),那么就会在myObject中添加一个foo属性,屏蔽原型链中的属性;
    b:原型链中存在foo属性,但被标记为只读(writable:false),那么无法修改已有属性或者在myObject上创建屏蔽属性。代码如果运行在严格模式下,代码会报错。否则,这条赋值语句会被忽略。总之,就是不发生屏蔽;
    c:原型链中存在foo属性,但它是一个setter(自己定义的赋值函数)。这种情况下,foo不会被添加到myObject中,也不会重新定义setter。
    注意:

    上边说的规则针对的只是myObject.foo = "bar"这种赋值方式。如果你希望b和c种情况也能生成新的屏蔽属性,那么就采用Object.defineProperty(..)这种方式来添加属性。

    reply
    0
  • 怪我咯

    怪我咯2017-04-10 16:12:08

    题主更改问题应该主动通知已答题者一声吧,要不别人看到先前的答案会感觉答非所问……

    之前的答案:
    “这和原型链没有任何关系啊...
    Object.defineProperty()方法修改了属性默认的特征,你设置了writable: false,就表示属性的值obj.x = 1是不可修改的,如果尝试为它指定新值,则在非严格模式下,赋值操作将被忽略;在严格模式下,复制操作将会导致抛出错误。
    参考《JavaScript高级程序设计(第3版)》6.1.1节 属性类型>>数据属性”

    reply
    0
  • Cancelreply