2014-10-04 67 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 
相关问题