日期:2014-05-16  浏览次数:20392 次

javascript prototype 问题
function Car() {
  debugger;
  Car.prototype.color = "red";
  Car.prototype.drivers = new Array("mike", "sue"); // 两个实例指向同一个数组,为什么?
}

var oCar1 = new Car();
var oCar2 = new Car();


oCar1.drivers.push("Matt");// 修改了oCar1 也修改oCar2 ,为什么呢?
alert(oCar1.drivers);
alert(oCar2.drivers);

请问一下:为什么car的两个实例oCar1,oCar2 的 drivers属性 会指向同一个数组?这样(我的理解是Car.prototype.drivers 每次new时,会在堆里创建对象,不会两次都指向同一个地址。)请高手从原理上解释一下。

------解决方案--------------------
在Car的构造函数里 你定义的是prototype里的对象-color,drivers;而不是属于Car的实例类的
实际上新建的Car对象oCar1,oCar2都没有属于自己的内部对象,而都是共有的,因为你是在prototype
里定义的,所以指向的都是同一地址,也就是说oCar1.drivers.push函数操作的是prototype里的共有
drivers,oCar2.drivers自然也就改变了
事实上,如果你用this来定义,一切都没问题了因为这样定义的color和drivers属于类实例本身
function Car() { 
this.color = "red"; 
this.drivers = new Array("mike", "sue"); // 两个实例指向同一个数组,为什么? 


------解决方案--------------------
javascript中,变量的类型可以分为原始值引用值,原始值类型就是值类型,引用值类型就是引用类型。
在javascript中,string属于原始值类型(这与其他语言不一样),而Array属于引用值类型。如果使用原型(prototype)来给对象添加成员,对于引用类型,所有的对象都是共享的,所以所有的对象会共享。

//可以这样修改
function Car() { 
debugger; 
Car.prototype.color = "red";
this.drivers = new Array("mike", "sue");
}

var oCar1 = new Car(); 
var oCar2 = new Car(); 

oCar1.drivers.push("Matt"); 
alert(oCar1.drivers); 
alert(oCar2.drivers);