【问题标题】:Inherited properties prevent setting actual properties?继承的属性阻止设置实际属性?
【发布时间】:2018-03-15 11:23:34
【问题描述】:

我正在尝试继承默认规范属性,这样,当我在继承规范中创建特定覆盖值时,我仍然可以访问(通过继承)未修改的规范值:

let default_boltSpec = {
  head_diameter: 2,
  shaft_diameter: 0.8,
};
Object.freeze(default_boltSpec);

let derivedBoltSpec = Object.create(default_boltSpec);
console.log( "derivedBoltSpec:", derivedBoltSpec );

Object.assign(derivedBoltSpec , {
  head_diameter: 1.5,
});

奇怪的是,我似乎不允许“覆盖”继承的值!严格位于原型链上的值如何以任何方式干扰允许我在对象上放置的属性?

编辑: 这张截图显示了在 Firefox Web 开发者控制台中运行上述代码 sn-p 的效果:

这张图片显示 Object.create 没有向创建的对象添加任何属性。这与the documentation 一致。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您已冻结对象。这也将冻结属性值。

    从上下文来看,我认为您要使用的是seal,而不是freeze。例如,

    let default_boltSpec = {
      head_diameter: 2,
      shaft_diameter: 0.8,
    };
    Object.seal(default_boltSpec);
    
    let derivedBoltSpec = Object.create(default_boltSpec);
    
    Object.assign(derivedBoltSpec , {
      head_diameter: 1.5,
    });
    console.log( derivedBoltSpec)

    Here are the docs for seal

    编辑:您必须再次使属性可写。您可以使用 Object.defineProperty 执行此操作。但是你基本上会遍历所有属性并使它们可写。例如,

    Object.defineProperty(derivedBoltSpec 'head_diameter:', { value: 1.5, enumerable: true, configurable: true, writable: true });
    

    【讨论】:

    • 我已经冻结了 prototype 对象('default_boltSpec')。我要修改的对象是“derivedBoltSpec”,它没有被冻结。
    • 但我什至没有尝试更改原型对象的属性。这就是为什么这非常令人困惑。冻结的原型对象在创建后永远不会被修改。
    • 冻结属性通过继承传播。使用 object.create,您基本上是将整个对象及其所有属性及其行为及其原型(在 proto 中)复制到新对象。
    • 虽然您的解释确实可以解释错误消息,但它依赖于一个有证据反对它的假设:假设任何属性都从 Object.create 的第一个参数复制到创建的对象上.我在我的问题中添加了这个证据。
    • 看看这个答案:stackoverflow.com/a/19698581/3719089 我说属性被复制是错误的,我应该清楚地提到这一点。
    猜你喜欢
    • 1970-01-01
    • 2019-03-09
    • 2015-11-01
    • 1970-01-01
    • 2013-01-05
    • 2019-01-23
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多