js继承的那些事

一、原型链继承(8.20)

1. 原理示例:
通过函数的prototype属性给其原型添加属性或方法!
缺点:继承的引用类型的数据,在实例后别其他实例改变,会跟着改变.

看例子:

function SuperType() {

}
SuperType.prototype.colors = ["red", "blue", "green"];

var instance1 = new SuperType();
instance1.colors.push("black");
console.log(instance1.colors); //[ 'red', 'blue', 'green', 'black' ]
var instance2 = new SuperType();
console.log(instance2.colors); //[ 'red', 'blue', 'green', 'black' ]

二、借用构造函数(8.21)

理解:解决原型链继承中对原型中引用数据类型的误删改
特点: 把父类私有的属性和方法,克隆一份一样的给子类私有的属性,Father执行的时候,把Father的中的this换成Son的实例,由于并不是new Father,所以Father.prototype上的属性无关.

function SuperType() {
    colors.call(this)
}

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

var instance1 = new SuperType();
instance1.colors.push("black");
console.log(instance1.colors); //[ 'red', 'blue', 'green', 'black' ]
var instance2 = new SuperType();
console.log(instance2.colors); //[ 'red', 'blue', 'green']

但他也有他的缺点: 方法都在构造函数中定义,函数复用无从谈起,另外超类型原型中定义的方法对于子类型而言都是不可见的。

三、组合继承(原型链 + 借用构造函数)(8.22)

特点: 组合继承指的是将原型链和借用构造函数技术组合到一块,从而发挥二者之长的一种继承模式。
理解: 使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承,既通过在原型上定义方法来实现了函数复用,又保证了每个实例都有自己的属性。

// 父类型
function Teacher(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

//子类型
function Student(name, age, sex, score) {
    //借用构造函数
    Teacher.call(this, name, age, sex);
    this.score = score;
}

Student.prototype = new Teacher(); // 此时 Student.prototype 中的 constructor 被重写了,会导致 s1.constructor === Teacher
Student.prototype.constructor = Student; //将 Student 原型对象的 constructor 指针重新指向 Student 本身
// 学生特有
Student.prototype.Exam = function () {
    console.log('大家好,我是学生,我是要考试的');
};
//此时s1就继承JPerson的属性和方法
var s1 = new Student('zs', 18, '男', 100);
console.log('s1',s1);//s1 Student { name: 'zs', age: 18, sex: '男', score: 100 }
var p1 = new Teacher('zs2', 28, '男');
console.log("p1",p1);//p1 Teacher { name: 'zs2', age: 28, sex: '男' }
console.log(s1.constructor === Teacher);//false

缺点: 无论什么情况下,都会调用两次超类型构造函数:一次是在创建
子类型原型的时候,另一次是在子类型构造函数内部。

四、冒充对象继承(8.23)

核心: 使用父类的构造函数来增强子类实例
特点: 把父类私有的和公有的克隆一份一样的给子类

function Son(){
    var temp = new Father()
    for(var k in temp){
        this[k] = temp[k]
    }
    temp = null
}

var son = new Son()
console.log(son.sleep()) // father正在睡觉
console.log(son.look('TV')) // father正在看TV

五、原型式继承

特点: ECMAScript5 通过新增 Object.create()方法规范了原型式继承。

这个方法接收两个参数:一个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象(可以覆盖原型对象上的同名属性),在传入一个参数的情况下,Object.create() 和 object() 方法的行为相同。

原型式继承的基本思路:

借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

function object(sourceObj) {
  function Man4() {};
  
  Man4.prototype = sourceObj;

  return new Man4();
}


var  Man4 = Object.create(Person4, {
   name: {
      value:
      enumerabel:
  }
})

// 以这种方式指定的任何属性都会覆盖原型对象的同名属性

六、ES6 继承

 class Person {
        constructor(name) {
            console.log(this.name)
            this.name = name || 'xixi';
        }

        names() {
            console.log(this.name)
        }
    }

    let p1 = new Person('wys')
    p1.names()//wys
	
	//继承Person 
    class children extends Person {
        constructor(name) {
            super(name);//父
        }
    }

    let p2 = new children('ii')
    p2.names()//'ii'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值