原型和继承

230 阅读1分钟

原型继承和原型污染

  • 父类的内部属性在继承后在子类的原型对象上,父类本身不会被修改。同时子类继承父类的属性后,所有子类的实例共同指向一个原型,所以会发生污染。
  • 父类与子类有相同命名的属性也不会冲突,子类优先使用自身定义的属性,如果没有找到就去找父类原型的属性
 function father(name) {
        this.name = name
        this.colors = ["red", "blue", "green"];
    }
    // father.prototype.colors = ["red", "blue", "green"];
    function son(name)  {
        this.name = name
    }
    son.prototype = new father('ppp'); 
    var p1 = new father()
    var son1 = new son('aaa');
    var son2 = new son();
    son1.colors.push("black");
    console.log(p1.colors, son1.colors, son2.colors); // 原型继承导致子类实例修改了原型上的变量和属性
  • 子类继承父类后,也会继承父类的原型,同样这个(爷爷辈)的原型也会被污染,从而影响到父类
 function father(name) {
        this.name = name
        // this.colors = ["red", "blue", "green"];
    }
    father.prototype.colors = ["red", "blue", "green"];
    function son(name)  {
        this.name = name
    }
    son.prototype = new father('ppp'); 
    var p1 = new father()
    var p2 = new father() 
    var son1 = new son('aaa');
    var son2 = new son();
    son1.colors.push("black");
    // 所有father类的实例都被污染了

不污染父类的继承

  • call 函数将父类的变量引用在子类中,不借助原型将属性一同交给子类本身,但不能继承父类原型上的方法
// function son() {
//     father.call(this)
// }
  • 浪费开销,每一个子类都用了父类
  • 虽然子类使用了父类的属性,但二者没有原型的关联,所以要将子类的原型关联到父类上
son.prototype.constructor = new father()

当父类原型上发生变化后,子类也能在原型上找到父类的原型并使用它的属性和方法