【问题标题】:JavaScript: assigning a value to a non enumerable property changes it to enumerable?JavaScript:将值分配给不可枚举的属性会将其更改为可枚举?
【发布时间】:2013-01-08 23:33:26
【问题描述】:

我想我在这里误解了一些东西。我有一个对象,其中包含我希望不可枚举的属性。我希望能够从对象的函数本身中为其赋值,但是当我这样做时,该属性变为可枚举的。

例子:

function ObjectNode() {
}

Object.defineProperty(ObjectNode.prototype, "parent", {
    value:null
    // enumerable and configurable default to false
}

// Pass an ObjectNode instance and set this object node as its parent
ObjectNode.prototype.addChild = function(node) {
    node.parent = this;    // <-- node.parent is now enumerable
    ...more code...
};

实际发生的情况是,为 node.parent 分配一个值会创建一个名为 parent 的新“自己”属性,它会覆盖原来的属性。

有没有一种方法可以在不这样做的情况下在内部为不可枚举的属性赋值?还是我必须求助于在闭包中引用变量的 getter/setter 属性?

编辑:

GGG 回答这个问题值得称赞,因为正是他的建议让我得到了最终的答案。

我想要做的实际上是从“for(key in object)”语句中隐藏一个简单的属性。我能够这样做:

function ObjectNode() {
    Object.defineProperty(this, "parent", {
        value:null, 
        writable:true
    });
}

我一开始对此犹豫不决的一个原因是错误地理解我不希望在每个实例中都重新创建该属性。但是,呃,这就是实例属性!!!

感谢 GGG,帮助我重新调整大脑!

【问题讨论】:

  • 乍看之下,原型的属性似乎仍然是不可枚举的,但您已经用对象本身的可枚举属性遮蔽了它。
  • 如果您使用有效的 JavaScript 代码示例会更清楚。
  • @alex,请参阅问题以获取代码示例;)
  • @GGG 例子本身 ObjectNode.prototype.addChild(node) { ... 充其量没有意义。
  • 是的,他忘记输入= function并关闭一组括号,但我认为意图很明确。

标签: javascript enumerable assign defineproperty


【解决方案1】:

您已经创建了原型属性的一个不可配置的属性,但它仍然可以被构造函数创建的对象的属性所遮蔽。

function ObjectNode() {
}

Object.defineProperty(ObjectNode.prototype, "parent", {
    value: null,
    configurable: false
})

ObjectNode.prototype.addChild = function (node) {
    node.parent = this;    // <-- node.parent is now enumerable
}

var mom = new ObjectNode();
var kid = new ObjectNode();

mom.addChild(kid);

console.log(kid.parent == mom);  // works, logs true

kid.parent = "foo";

console.log(kid.parent);  // works, logs "foo"

ObjectNode.prototype.parent = "foo"; 

console.log(ObjectNode.prototype.parent); // fails, logs null

要记住的是,对象的属性只是该对象的属性,而不是原型链中具有该对象的其他对象的属性。相反,请尝试在构造函数中创建新对象的不可配置属性:

function ObjectNode() {
    Object.defineProperty(this, "parent", {
        value: null,
        configurable: false
    })
}

当然,这将阻止您的addChild 函数工作,因为该属性不再是可配置的。您可以考虑在该函数中定义属性,但在使用addChild 设置之前,它仍然是可配置的。

总而言之,一般来说,最好的选择是不要担心如果它不是绝对关键(而且我不确定它会在什么情况下)使事情变得不可配置。很长一段时间以来,如果没有该功能,世界就相处得很好。 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2012-05-03
    相关资源
    最近更新 更多