javascript原型链继承,为什么会出现这种情况,求大神解答?

 function SuperType() {
            this.colors = ["red", "blue", "green"];
        }

        function SubType() {}

        SubType.prototype = new SuperType();    //继承方法
        var instance1 = new SubType();
        console.log(instance1.colors);
        instance1.colors.push("black");
        console.log(instance1.colors);

        var instance2 = new SubType();
        console.log(instance2.colors);

执行过后,明明只在instance1中的colors数组push一个black,为什么在instance2中会出现,不是又new出来一个新的对象了吗?而且原型中的方法会共享,但继承的对象中,colors属性存在SuoerType实例上呀,为什么会影响到instance2?求大神解答。

图片说明

SubType.prototype = new SuperType(); //继承方法
你这是一个比较常见继承方法,它是通过把子类的原型对象(prototype)设置成父类的一个实例来进行继承的。
但是只简单的这样设置继承有三个缺点:

  缺点一:执行上面代码会发现父类的构造函数不是像JAVA中那样在给子类进行实例化时执行的,而是在设置继承的时候执行的,并且只执行一次。这往往不是我们希望的,特别是父类的构造函数中有一些特殊操作的情况下。

  缺点二:由于父类的构造函数不是在子类进行实例化时执行,在父类的构造函数中设置的成员变量到了子类中就成了所有实例对象公有的公共变量。由于JavaScript中继承只发生在“获取”属性的值时,对于属性的值是String,Number和Boolean这些数据本身不能被修改的类型时没有什么影响。但是Array和Object类型就会有问题。

  缺点三:如果父类的构造函数需要参数,我们没有办法在实例化时传递参数。

应该用下面方式继承

        function SuperType() {
            this.colors = ["red", "blue", "green"];
        }
        function SubType() {
            SuperType.call(this);
        }
        SubType.prototype = Object.create(SuperType.prototype);
 SubType.prototype = new SuperType();

这个语句其实已经重写了SubType的原型链(就是用新的值覆盖了之前的值),其实你可以把SubType理解为对象,prototype理解为这个对象的一个比较特殊的属性。
这时你可以通过SubType.prototype.colors拿到这个数组的引用。
然后执行下面语句的时候

 var instance1 = new SubType();

此时你可以通过instance1.colors也能拿到SubType.prototype.colors同样的数组的引用,这两个是同样的引用(指向同一块内存)。
这里分析一下你拿这个instance1.colors的值,实际上是你在instance1.colors的时候,程序发现在这个对象上没有这个值,这时候就去这个对象的原型链上(也就是instance1.__proto__,如果没有就去instance1.__proto__.__proto__...依此类推)去找这个colors看有没有,结果找到了colors这时才返回给你。
这时往下执行instance1.colors.push("black"),其实效果跟SubType.prototype.colors.push("black")一样的(同一个引用)

总结一下知识点:
1.引用赋值
2.pototype和__proto__
3.new的时候做了什么事情
最后就能理解这个继承到底做了什么事了

--可能有些地方表达有误。

这个涉及到一个复杂值传递的问题,在js中数组属于object复杂数据类型,在赋值的过程中赋值给变量的是一个地址,
你把一个地址赋给一个变量,同时在变量中对地址所指向的数据进行了修改,那么这个数据就会被修改,在后面的过程中,你把这个地址再赋给其他变量
当然会得到已经发生改变的值。