- 系列分享
寒潮ing,你可能在FaceTest中遇到(1)—— new运算符及手动实现
寒潮ing,你可能在FaceTest中遇到(2)—— 常用的排序算法
寒潮ing,你可能在FaceTest中遇到(3)—— what's this
创建一个基础的父类构造函数
function God(name='god',age='88') {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
}
}
God.prototype.sayAge = function() {
console.log(this.age);
}
我们可以通过下面的几种继承方式获得父类的
1.原型链继承
function Son(name='son') {
this.name = name;
}
Son.prototype = new God();
let mySon = new Son();
console.log(mySon.name);//son
console.log(mySon.age);//88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
实现比较简单,但是 原型对象的所有属性被所有实例共享
借用原型链继承上面代码
let mySon1 = new Son();
let mySon2 = new Son();
mySon1.age = '18';
console.log(mySon2.age);//18
2.构造继承
function Son(name='son') {
God.call(this);
this.name = name;
}
let mySon = new Son();
console.log(mySon.name);//son
console.log(mySon.age);//88
mySon.sayName();// son
mySon.sayAge();// undefined
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// false
let mySon1 = new Son();
let mySon2 = new Son();
mySon1.age = '18';
console.log(mySon2.age);//88
构造继承避免了共享属性的问题,但是不能继承父类原型上的属性或者方法,实例化对象是子类(Son)
3.组合继承
function Son(name='son') {
God.call(this);
this.name = name;
}
Son.prototype = new God();
// 注意这里要改变constructor 指向
Son.prototype.constructor = Son;
let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
综合了原型链继承和组合继承的优点,除了调用两次父类外几乎无缺点
4.实例继承
function Son(name='son') {
let instance = new God();
instance.name = name;
return instance
}
let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// false
console.log(mySon instanceof God);// true
继承的是父类God,而不是子类Son
5.拷贝继承
function Son(name='son') {
let obj = new God();
for (let key in obj) {
Son.prototype[key] = obj[key]
}
Son.prototype.name = name;
}
let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// false
缺点比较明显,需要多次循环,而且无法遍历不可枚举属性
6.寄生组合继承
function Son(name='son') {
God.call(this);
this.name = name;
}
// 立即执行函数
(function() {
// 创建一个中间函数
let Mid = function() {}
Mid.prototype = God.prototype;
Son.prototype = new Mid();
})()
// 注意这里要改变constructor 指向
Son.prototype.constructor = Son;
let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
缺点是实现复杂,几乎完美的继承
7.9012年了 ES6的class继承该用起来了
class God {
constructor(name='god',age='88') {
this.name = name;
this.age = age;
}
}
class Son extends God {
constructor(name='son',sex='M') {
super(name);
this.sex = sex;
}
}
let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
console.log(mySon.sex);// M
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true