2015-09-25 77 views
1

考虑下面的代码Nodejs为什么数组用静态原型初始化?

Class = function() 
{ 
    //this.array = []; 
} 

Class.prototype.array = []; 
Class.prototype.str = null; 

var a = new Class(); 
var b = new Class(); 

a.array.push("a"); 
console.log (a.array); 
b.array.push("b"); 
console.log (b.array); 

a.str = "a"; 
console.log (a.str); 
console.log (b.str); 
b.str = "b"; 
console.log (a.str); 
console.log (b.str); 

如果我们运行原样,我们会发现,修改类的array在任何情况下,都静态完成 - 在a改变阵列反映在b和副反之亦然。但是,修改str变量,虽然初始化方式与array不一样。

如果我们在构造函数中取消注释行,那么在任何情况下对数组的更改都不会静态完成。

我偶然发现了一个nodejs错误?我无法在任何地方找到有关这种情况的详细信息,因此任何人都可以解释为什么nodejs有这种行为?

+3

Node和浏览器中的行为没有区别。这只是JavaScript的工作方式。 – Pointy

回答

3

对象属性的赋值(直接将赋值给对象属性)总是会导致目标对象本身的属性。 查找的属性,另一方面,将咨询原型链。

当你改变这是目前在原型的数组的内容:

a.array[0] = "foo"; 
你修改时属性“阵列”通过对象“一”抬头发现对象

。该值在原型上找到,因此这是属性值分配中使用的值。该陈述在结构上是:

(someObject)[0] = "foo"; 

并且这里的“someObject”是在原型上找到的那个数组。

但在这里,你直接在对象上设置属性:

a.str = "foo"; 

的JavaScript总是创建或直接在此情况下,目标对象上更新的属性,并不会触及原型链在所有。

+0

所以基本上'a.array'和'b.array'是对'Class.prototype.array'的引用?对不起,如果我使用了错误的术语,我来自C++背景。 – Catalin

+1

右键 - 实例上不存在“数组”属性(除非您在构造函数中取消注释该行),因此可以在原型上找到它。这是一个不错的主意,因为尽管JavaScript *看起来很相似,但它完全不同,因此忘记了C++中关于类和继承的所有知识。 – Pointy

+0

@Pointy,你的意思是参考对象?即(typeof dataType =='object'),看起来你的推理对于引用对象以及..(即a.myObject。anyProperty =“anyValue”在b.myObject.anyProperty =“anyValue”上会产生同样的效果)一旦你赋值a.myObject.anyProperty,b.myObject.anyProperty将具有相同的值 – g2000

2

这不是一个错误。通过这样做

Class.prototype.array = []; 

创建共享属性。但通过做

instance.array = [] 

您创建一个实例属性,它既不共享也不跨实例可见。通过在构造函数中执行this.array = [];,您可以覆盖共享引用。

相关问题