2014-10-04 88 views
1

爲什麼原型與普通物體不同?原型和對象屬性。他們爲什麼行事不同?

var obj={'length':4} 

obj._length=obj.length 

console.log(obj._length); // 4 

數組是一個對象,它的原型是太多,所以同樣的行爲應被視爲...

var a=[0,1,2,3]; 


Array.prototype._length=Array.prototype.length; 


console.log(a.length,a._length); // 4,0 

我不會在實踐中使用,但我確實想更好地理解這裏發生了什麼。

編輯:你會如何看到相同的行爲?

+0

是不是真的有差別。第二個例子中的錯誤是,你認爲'Array.prototype.length === a.length',這不是caee。 – 2014-10-04 14:54:20

回答

3

在第一種情況下,您將在對象上創建一個名爲_length的新屬性,併爲其分配length屬性的值。所以,改變一個不會影響另一個。您可以確認它像這樣

var obj={'length':4} 
obj._length=obj.length 
console.log(obj._length); 
# 4 
obj.length = 15; 
console.log(obj._length); 
# 4 

在你的第二個情況下,當你創建一個數組對象,該length屬性將對象本身的設置,反之,_length是在原型鏈,而不是對象本身。

console.log(a.hasOwnProperty("length"), a.hasOwnProperty("_length")); 
# true false 

而且,你已經創造了Array的原型一個變量名_length,默認長度0console.log(Array.prototype.length);)。因此,所有後續的數組也會擁有該屬性。

var a = [0, 1, 2, 3]; 
Array.prototype._length = Array.prototype.length; 
console.log([]._length); 
# 0 

所以,我們在這裏談論兩個不同的屬性。 length特定於所有Array對象,其中_length對所有Array對象都是共有的。

您可以確認這樣

var a = [0, 1, 2, 3]; 
Array.prototype._length = Array.prototype.length; 
console.log([1, 2, 3]._length); 
# 0 
console.log([1, 2, 3, 4]._length); 
# 0 

由於_length不是自己,當您嘗試訪問他們,他們查找原型鏈找到一個在Array.prototype。因此,他們都被打印0

如果你想用_length屬性來獲取length,你可以在原型定義它,像這樣

Object.defineProperty(Array.prototype, "_length", { 
    get: function() { 
     return this.length; 
    }, 
    set: function(newValue) { 
     this.length = newValue; 
    } 
}); 

console.log([]._length); 
# 0 
console.log([1, 2, 3]._length); 
# 3 
相關問題