2013-01-25 77 views
3

我想我在這裏誤解了一些東西。我有一個對象,其中包含一個我希望不可枚舉的屬性。我希望能夠從對象的函數本身中爲它賦值,但是當我這樣做時,該屬性變爲可枚舉。JavaScript:將值賦給非枚舉屬性將其更改爲可枚舉?

例子:

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值創建一個新的「自己」的屬性稱爲父,這將覆蓋原來的。

有沒有一種方法,我可以內部分配一個值不枚舉的屬性,而不這樣做?或者我必須訴諸getter/setter屬性來引用閉包中的變量?

編輯:

GGG值得稱讚回答這個問題,因爲這是他的意見,使我對我的最終答案。

我想要做的就是從'for(key in object)'聲明中隱藏一個簡單的屬性。我能做到這一點是這樣:

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

一個原因我在這猶豫下手的是,我不想的財產,以每個實例重新創建了錯誤的理解。但是,呃,這是一個實例屬性!

謝謝GGG幫助我重新調整我的大腦!

+1

一目瞭然,它看起來像原型的屬性仍然是不可枚舉的,但是你已經用對象本身的枚舉屬性對它進行了映射。 –

+0

如果您使用了有效的JavaScript代碼示例,它會更清晰。 – alex

+0

@alex,請參閱該代碼示例的問題;) –

回答

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

總而言之,一般你最好的選擇是不需要擔心的事情不可配置的,如果它不是絕對重要的(我不知道哪裏會是任何情況下)。很長一段時間以來,這個世界一直沒有那麼好的功能。 ;)