JavaScript:为非枚举属性赋值将其更改为可枚举?

时间:2013-01-25 02:31:18

标签: javascript enumerable assign defineproperty

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

示例:

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,帮助我重新调整我的大脑!

1 个答案:

答案 0 :(得分:2)

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

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设置之前,它仍然是可配置的。

总而言之,一般来说,最好的选择是不要担心如果事情不是绝对关键的话就不可配置(而且我不确定它会是什么情况)。长期以来,没有这种功能,世界已经相当顺利。 ;)