//1.构造函数(利用call等改变this指向)-----------同比创建对象的构造函数模式
function Parent1() {
this.name = '父'
}
function Son1() {
Parent1.call(this); //将子类的this使用父类的构造函数跑一遍
}
var s1 = new Son1();
console.log(s1 instanceof Parent1); // false
console.log(s1 instanceof Son1); //true
//特点:可以实现多继承(call);可以向父类传参;子类实例共享父类成员(非原型上的)
//缺点:Person1原型链上的成员不会被子类继承
//2.原型链继承(将父类的实例作为子类的原型)-----------同比创建对象的原型链模式
function Parent2() {
this.name = '原型链';
}
function Son2() {
this.type = 'child';
}
Son2.prototype = new Parent2();
var s2 = new Son2();
console.log(s2 instanceof Parent2); // true
console.log(s2 instanceof Son2); // true //
//特点:实例时子类的实例也是父类的;父类新增的原型方法/属性,子类都能访问
//缺点:无法实现多继承;来自原型对象的所有属性被所有实例共享;创建子类实例时,无法向父类传参
//3.实例继承(为父类添加新特性,作为子类实例返回)-----------同比创建对象的工厂模式
function Parent3() {}
function Son3(name) {
var s = new Parent3();
s.name = '实例继承'
return s;
}
var s3 = new Son3();
var s31 = Son3();
console.log(s3 instanceof Parent3); // true
console.log(s3 instanceof Son3); //false
console.log(s31 instanceof Parent3); // true
console.log(s31 instanceof Son3); //false
//特点:不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
//缺点:实例是父类的实例,不支持多继承
//4.拷贝继承
function Parent4() {}
function Son4() {
var p = new Parent4();
for (var k in p) {
Son4.prototype[k] = p[k];
}
}
var s4 = new Son4();
console.log(s4 instanceof Parent4); // false
console.log(s4 instanceof Son4); //true
//特点:支持多继承
//缺点:效率低,占内存(拷贝父属性)
//5组合继承(调用父类构造,继承父成员,然后将父实例作为子原型,实现函数复用)
function Parent5(name) {}
function Son5(name) {
Parent5.call(this);
}
Son5.prototype = new Parent5();
var s5 = new Son5();
console.log(s5 instanceof Parent5); // true
console.log(s5 instanceof Son5); //true
//特点:可以继承实例属性方法,也可以继承原型属性方法;即是子类实例也是父类;可以传参
//缺点:调用了俩次父类构造函数,生成了俩实例,多占内存
//6.寄生组合继承()
function Parent6() {}
function Son6() {
Parent6.call(this);
}
Son6.prototype = Object.create(Parent6.prototype);
//记得new过程吗,前两步(创建空对象,将构造函数的原型对象赋值给空对象 对象原型)
//修复this指向
Son6.prototype.constrctor = Son6
var s6 = new Son6();
console.log(s6 instanceof Parent6); // true
console.log(s6 instanceof Son6); //true
//实现复杂
//7.ES6
class People {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name} eat food`)
}
}
//继承父类
class Woman extends People {
constructor(name) {
//继承父类属性
super(name);
}
eat() {
//继承父类方法
super.eat();
}
}
let wonmanObj = new Woman('wang');
wonmanObj.eat();
//es6,class中只能定义方法,不能定义对象变量等,没有prototype,必须用new调用
用原生封装继承
//原生继承(就是将寄生组合修改了一下)
function extendsClass(Parent, Son) {
function O() {}
O.prototype = parent.prototype;
Son.prototype = new O();
Son.prototype.constrctor = Son;
return Son;
}
本文深入探讨JavaScript中的七种经典继承模式,包括构造函数、原型链、实例继承、拷贝继承、组合继承、寄生组合继承及ES6继承,对比各自的优缺点,帮助读者理解并选择适合场景的继承方式。

被折叠的 条评论
为什么被折叠?



