通过代码明白继承那些事

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构造函数中。如果父类中的地址引用属性太多。那么最好是在子类构造中,重新调用父类构造。

猜你喜欢

转载自bingsizi.iteye.com/blog/2348064