将新属性分配给已冻结原型的空对象 [英] Assign new property to empty object which has frozen prototype

查看:105
本文介绍了将新属性分配给已冻结原型的空对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我不能将新属性分配给已冻结原型的非冻结对象:

Why can't I assign new properties to non-frozen object, which has frozen prototype:

无Object.freeze工作:

Working without Object.freeze:

'use strict'
//This object will be prototype of next objects
var defaults = {
  name: 'def name', 
  sections: {
    1: {
      secName: 'def sec name'
    }
  }
};

//So we have an empty object with prototype set to our default object.
var specificObject = Object.create(defaults);


specificObject.sections = {};
console.log(specificObject.hasOwnProperty('sections')); //true

specificObject.sections['1'] = Object.create(defaults.sections['1']);

上面的代码按预期工作,但我想确保不会意外更改默认值。所以我想冻结我的默认对象:

Above code works as expected, but I want to make sure that defaults won't be accidentally changed. So I want to freeze my defaults object:

'use strict'
//This object will be prototype of next objects
var defaults = {
  name: 'def name', 
  sections: {
    1: {
      secName: 'def sec name'
    }
  }
};

//!!!!!!!!!!!!
Object.freeze(defaults);

//So we have an empty object with prototype set to our default object.
var specificObject = Object.create(defaults);

//TypeError: Cannot assign to read only property 'sections' of #<Object>
specificObject.sections = {};
console.log(specificObject.hasOwnProperty('sections')); //true

specificObject.sections['1'] = Object.create(defaults.sections['1']);

我没有得到的是为什么如果原型被冻结我不能分配给specificObject?

What I don't get is why can't I assign to specificObject if its prototype is frozen?

//编辑:
请注意,特定对象未被冻结:

// Notice that specific object is not frozen:

'use strict'
//This object will be prototype of next objects
var protoObj = {a: 1, o: {}};
Object.freeze(protoObj);

console.log(Object.isFrozen(protoObj)); //true

var n = Object.create(protoObj);
console.log(Object.isFrozen(n)); //false


推荐答案


什么我不明白为什么我不能分配给 specificObject 如果它的原型被冻结了?

What I don't get is why can't I assign to specificObject if its prototype is frozen?

因为属性属性是继承的。是的,这很奇怪。

Because property attributes are inherited. Yes, it's odd.

如果冻结一个对象,它将设置 [[可写]] 属性所有数据属性为 false

If you freeze an object, it will set the [[writable]] attribute of all data properties to false.

如果您分配给对象属性,但该属性不存在于对象,它会在原型上查找它 - 它可能被定义为setter。当这个查找将返回并且说有一个该名称的属性但它是不可写的时,你的赋值将失败(并以严格模式抛出)。

If you assign to an object property, but that property does not exist on the object, it will go and look it up on the prototype - it might be defined as setter there. When this lookup will return and say that there is a property of that name but it is non-writable, your assignment will fail (and throw in strict mode).

什么你可以反对吗?


  • 使用 Object.defineProperty 而不是赋值,它不检查原型

  • 或类似地,使用 Object.create 的第二个参数来创建自己的属性

  • 仅在您分配到 specificObject 后冻结默认值

  • Use Object.defineProperty instead of assignment, it doesn't check the prototype
  • or similarly, use the second parameter of Object.create to create the own property
  • freeze the defaults only after you've assigned to specificObject.

这篇关于将新属性分配给已冻结原型的空对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆