1. 原型链继承
利用原型链来实现继承,父类的一个实例作为子类的原型
function child(){
this.xx = 'xx'; //子类自己的定义
}
child.prototype = new parent();
//这里new parent()父类对象并没有constructor属性,需要后面加上
child.prototype.constructor = child
原理: 子类的原型对象
指向 父类的实例
, 当子类实例
找不到属性和方法时,会沿着原型链往上找。
优点:简单,既是子类实例也是父类实例,父类新加原型方法或者属性,子类都能访问到
缺点:
- 不能实现多继承,所有子类的实例的原型都共享一个父类实例属性和方法
- 不能传参
2. 构造函数继承
通过使用call、apply方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例
原理: 子类的构造函数中执行父类的构造函数,并且改变子类的this绑定
// 创建子类、添加子类属性。
function arrange(name){
Person.call(this,name) // 执行父构造,将This指向本身,拉取父私有属性;
}
优点:简单,直接父类的属性和方法
缺点:无法继承原型链上的属性方法
3. 寄生组合式继承
将父类原型对象直接赋值给子类的构造函数,再将空属性的构造函数实例赋值给子类原型对象
function Parent(name){
this.name = name
}
Parent.prototype.getName = function(){
return this.name
}
// 创建子类、添加子类属性。
function Child(name){
Parent.call(this, name)// 执行父构造,将This指向本身,拉取父私有属性;
}
// 子类的原型对象指向父类的原型对象
Child.prototype = Parent.prototype
// 将constructor指向本身,保证原型链不断。
Child.prototype.constructor = Child
优点:完美实现继承,解决了组合式继承带两份属性的问题; new Child的时候不用 每次都 new Parent
缺点: 子类的prototype添加方法会影响 父类的prototype;
4. 寄生组合式继承(改进)
将父类原型对象直接赋值给子类的构造函数,再将空属性的构造函数实例赋值给子类原型对象
function Parent(name){
this.name = name
}
Parent.prototype.getName = function(){
return this.name
}
// 创建子类、添加子类属性。
function Child(name){
Parent.call(this, name)// 执行父构造,将This指向本身,拉取父私有属性;
}
// 子类的原型对象指向父类的原型对象
// 浅拷贝 解决问题
Child.prototype = Object.create(Parent.prototype)
// 将constructor指向本身,保证原型链不断。
Child.prototype.constructor = Child
优点:完美实现继承,解决了组合式继承带两份属性的问题; new Child的时候不用 每次都 new Parent
5. 克隆原型链继承
将等待继承的原型对象克隆,再赋值给继承的原型对象
// 创建子类、添加子类属性。
function arrange(name){
this.name = name;
this.goShop = function(food){
console.log(name + '叫你去买'+ food)
}
}
// 创建克隆类型
function Clone(obj){
for(var key in obj){
this[key] = typeof obj[key] == 'object' ? new Clone(obj[key]) : obj[key];
}
}
// 使用Clone构造函数继承原型
arrange.prototype = new Clone(Person.prototype);
// 将constructor指向本身,保证原型链不断。
arrange.prototype.constructor = arrange;
//创建arrange新实例,也是Clone实例,却不在是Person实例;
var newObj = new arrange('李四');
console.log(newObj instanceof Person) //false
console.log(newObj instanceof arrange) //true
console.log(newObj instanceof Clone) //true
// 克隆成功,可以访问克隆对象的原型对象;
console.log(newObj)
console.log(newObj.name) // 李四
newObj.eat('苹果'); // 李四正在吃:苹果
newObj.goShop('香蕉'); // 李四叫你去买香蕉
优点:直接通过对象生成一个继承该对象的对象
缺点:不是类式继承,而是原型式基础,缺少了类的概念
参考: https://www.jb51.cc/note/413574.html
https://blog.csdn.net/qq_42926373/article/details/83149347