1.首先写两个构造函数,父类拥有两个属性.name和数组arr
//父类 function Super(){ this.name = null; this.arr = []; } //子类 function Sub(){ }
2.让子类Sub继承父类的原型链中所有属性和方法,先不考虑constructor
Sub.prototype = new Super();
3.实例化一个子类对象.并打印属性值.结果为sub1和 1.结果正确
var sub1 = new Sub(); sub1.name = "sub1"; sub1.arr[0] = 1; alert("name:"+sub1.name+","+"arr:"+sub1.arr[0]);
4.重点来了,我们再来实例化一个变量。并且直接打印name和arr[0]属性。这个时候发现。name是属于自己的没有问题。但是arr[0]却把sub1的值也打印出来了。
var sub2 = new Sub(); alert("name:"+sub2.name+","+"arr:"+sub2.arr[0]);
总结:直接揭晓答案吧。因为在原型链中继承的时候。如果是值引用的属性直接继承没有问题。但是如果是地址引用的属性。则所有的实例会共用同一个属性。也就是说 arr是一个数组。属于地址引用。所以sub1和sub2会共用这个属性。因此在继承的时候要尽量避免继承父类中的值引用属性.如果不可避免可以在子类中单独声明这个变量。就是说把Super中的arr属性 移到Sub构造函数中。如果父类中的地址引用属性太多。那么最好是在子类构造中,重新调用父类构造。