原型链继承:
/*
* 特点:
* 1. JS继承也不像其他语言中的继承一样(其他语言:子类继承父类,就是拷贝一份父类的属性和方法),js中他是把父类的实例放到子类的原型链上,子类实例想要去调用这些属性和方法的时候,实际上是基于__proto__原型链查找的形式去完成的
* 2. 子类实例可以直接修改父类上的方法(这样就会导致其他父类实例都会收到影响)
* 3. 父类中私有的属性和方法,在实现原型链继承之后都会变成子类公有的属性和方法
* */
function Father(name, age) {//原型链继承
this.name = name
this.age = age
}
Father.prototype.sing = function () {
console.log('我会唱歌');
}
function Child(sex, hobby) {
this.sex = sex
this.hobby = hobby
}
Child.prototype = new Father('刘德华', 18)
Child.constructor = Child
let child = new Child('男', '唱歌')
console.dir(child);//age: 18 hobby: "唱歌" name: "刘德华" sex: "男"
child.sing()//我会唱歌
Call方法继承(构造函数继承):
//CALL继承的特点
//在Child方法中把Parent当作普通的函数执行,让Parent中的this指向Child的实例, 相当于给Child的实例设置了私有的属性和方法
/*
* 1.只能继承父类的私有属性和方法(因为只是把Parent当作普通函数执行了一次,跟Parent的原型上的方法和属性没有任何关系)
* 2.父类私有的属性和方法都会变成子类私有的属性和方法
* */
function Father(name, age) {//Call方法继承
this.name = name
this.age = age
}
Father.prototype.sing = function () {
console.log('我会唱歌');
}
function Child(sex, hobby) {
Father.call(this, '刘德华', 18)
this.sex = sex
this.hobby = hobby
}
let child = new Child('男', '唱歌')
console.log(Child.constructor);
console.dir(child);//age: 18 hobby: "唱歌" name: "刘德华" sex: "男"
child.sing()//报错 无法继承公有方法和属性
组合式继承:
//结合原型链继承和借用构造函数继承的方法
//特点
/*
* 1.子类实例可以使用父类的私有属性和方法
* 2.父类私有的属性和方法也会变成子类实例私有的属性和方法
* 3.子类实例父类公有的属性和方法
* 4.子类的原型链上会存在一份多余的父类私有属性
* */
function Father(name, age) {//组合方法继承
this.name = name
this.age = age
}
Father.prototype.sing = function () {
console.log('我会唱歌');
}
function Child(sex, hobby) {
Father.call(this, '刘德华', 18)
this.sex = sex
this.hobby = hobby
}
Child.prototype = new Father('刘德华', 18)
Child.constructor = Child
let child = new Child('男', '唱歌')
console.log(Child.constructor);
console.dir(child);//age: 18 hobby: "唱歌" name: "刘德华" sex: "男" 原型链上多了一份私有属性 继承了两次
child.sing()//我会唱歌
寄生组合继承:
//结合原型链继承和借用构造函数继承的方法,同时需要自己创建prototype,实现寄生组合式继承
//特点
/*
* 1.最完美的JS继承解决方案
* 2.父类私有的属性和方法,子类实例私有的属性和方法
* 3.父类公有的属性和方法,子类实例公有的属性和方法
* 4.子类实例修改公有的属性和方法不会影响父类的实例
* */
function Father(name, age) {//寄生方法继承
this.name = name
this.age = age
}
Father.prototype.sing = function () {
console.log('我会唱歌');
}
function Child(sex, hobby) {
Father.call(this, '刘德华', 18)
this.sex = sex
this.hobby = hobby
}
Child.prototype = Object.create(Father.prototype)
Child.constructor = Child
Child.prototype.dance = function () {
console.log('我会跳舞');
}
let child = new Child('男', '唱歌')
console.log(Child.constructor);
console.dir(child);//age: 18 hobby: "唱歌" name: "刘德华" sex: "男" 最完美的继承方法
child.sing()//我会唱歌
child.dance()//我会跳舞