为什么我可以设置不可配置属性描述符的[可枚举性和可写性]? [英] Why can I set [enumerability and] writability of unconfigurable property descriptors?

查看:176
本文介绍了为什么我可以设置不可配置属性描述符的[可枚举性和可写性]?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

https://developer.mozilla.org/en/JavaScript/ Reference / Global_Objects / Object / defineProperty 声明:


可配置
如果为真并且仅当可以更改此属性描述符的类型并且可以从相应对象中删除该属性时。默认为 false

所以,我有一个

var x = Object.defineProperty({}, "a", {
    value:true,
    writable:true,
    enumerable:true,
    configurable:false
});

现在我可以玩 xa = false for(i in x)等。但即使描述符 应该是不可配置的,我也可以这样做

Now I can play with x.a = false, for(i in x) etc. But even though the descriptor is should be unconfigurable, I can do

Object.defineProperty(x, "a", {writable:true}); // others defaulting to false
Object.defineProperty(x, "a", {}); // everything to false
Object.freeze(x); // does the same to the descriptors

反过来,再次将它们设置为true,或者尝试定义访问器描述符,现在引发错误。确切地说: Object.defineProperty:对不可配置属性的无效修改

The other way round, setting them to true again, or trying to define an accessor descriptor, raises errors now. To be exact: Object.defineProperty: invalid modification of non-configurable property.

为什么我可以降级描述符虽然他们说它们是不可配置的?

Why can I "downgrade" descriptors though they say they were non-configurable?

推荐答案

首先,即使可配置 false 可写可以从更改 false 。当可配置 false 时,这是唯一允许的属性更改。这种转换是允许的,因为一些内置属性包括(最值得注意的)数组的 length 属性(包括 Array.prototype )被指定为 writable:true,configurable:false 。这是以前ECMAScript版本的遗产。如果可配置:false 阻止将可写 true 更改为 false 那么就不可能冻结数组。

First, even when configurable is false, writable can be changed from true to false. This is the only attribute change allowed when configurable is false. This transition was allowed because some built-in properties including (most notably) the length property of arrays (including Array.prototype) are specified to be writable: true, configurable: false. This is a legacy of previous ECMAScript editions. If configurable: false prevented changing writable from true to false then it would be impossible to freeze arrays.

Object.defineProperty 不像你假设的那样有效。特别是,它如何处理属性描述符的工作方式取决于属性是否已存在。如果属性不存在,则描述符应提供所有属性的定义,以便在使用描述符创建属性之前为描述符中的任何缺少的属性分配默认值。但是,对于已存在的属性,描述符将从属性的当前属性设置中视为一组增量更改。未更改描述符中未列出的属性。此外,在delta描述符中具有与当前属性属性值相同的值的属性也被认为没有变化。所以以下都是合法的:

Object.defineProperty doesn't work quite like you're assuming. In particular, how it processes the property descriptor works differently depending upon whether or not the property already exists. If a property does not exist, the descriptor is supposed to provide a definition of all attributes so any missing attributes in the descriptor are assigned default values before the descriptor is used to create the property. However, for an already existing property the descriptor is taken as a set of delta changes from the current attribute settings of the property. Attributes that are not listed in the descriptor are not changed. Also, a attribute that has the same value in the delta descriptor as the current property attribute value is also consider no change. So the following are all legal:

Object.defineProperty(x, "a", {writable:false}); // can always change writable to false.
                                                //others attributes, not changed
Object.defineProperty(x, "a", {});     // no attributes, so nothing changes
Object.freeze(x); // same as Object.defineProperty(x, "a", {writable:false});
Object.defineProperty(x, "a", {enumerable:true, configurable: false}); //no change, 

这篇关于为什么我可以设置不可配置属性描述符的[可枚举性和可写性]?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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