ES6继承方法
class Father{
constructor(name,age){
this.name = name || 'han';
this.age = age || 10;
this.say = function () {
console.log("222");
}
}
}
class Son extends Father{
constructor(name,age,sex){
super(name,age); // 继承父类
this.sex = sex || '男' // 子类属性
}
}
let con = new Son();
con.say(); // 222
console.log(con.name); // han
console.log(con.age); // 10
console.log(con.sex); // 男
ES5继承方法
function Buff(name) {
this.name = name;
}
function _extends(Auff,Buff) {
Auff.prototype.__proto__ = Buff.prototype;
Auff.prototype.constructor = Auff;
Object.setPrototypeOf(Auff,Buff);
}
function Auff(name,age) {
_extends(Auff,Buff);
Object.getPrototypeOf(Auff).call(this,name);
this.age = age;
return this;
}
let a = new Auff('han',18);
console.log(a.name);
console.log(a.age);
// 父类
function Father(name,age) {
this.name = name;
this.age = age;
this.say = function () {
console.log("222");
}
}
Father.prototype.run = function () {
console.log("run")
};
1、原型链继承
将父类的实例作为子类的原型
优点:能通过instanceOf和isPrototypeOf的检测
缺点: 创建子类型的时候,不能像父类型的构造函数中传递参数。
function Son(){
this.second = 'han';
}
Son.prototype = new Father('mo',18);
Son.prototype.constructor = Son;
let son = new Son();
son.say();
console.log(son.age);
console.log(son.name);
console.log(son.second);
2.借用构造函数继承
在子类的内部调用父类,通过call改变父类中this的指向
优点:解决了Con中的私有属性变公有的问题,可以传递参数
缺点:1)方法在函数中定义,无法得到复用,每个子类都有父类实例函数的副本,影响性能;
2)无法继承原型中的方法;
3)实例并不是父类的实例,只是子类的实例
function Son(name,age) {
Father.call(this,name,age);
this.con = function () {
console.log("con");
}
}
let con = new Son('han',18);
con.con();
con.run();
3、组合继承(常用)
结合原型链继承和借用构造函数继承
优点:可以继承父类原型上的属性,可以传参,可复用;每个新实例引入的构造函数属性是私有的。
缺点: 调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
function Son(name) {
Father.call(this,name,age); //借用继承模式
}
Son.prototype = new Father('mo',18);// 原型链继承模式
Son.prototype.constructor = Son;
let con = new Son('han',18);
console.log(con.name)
4、 原型式继承
用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。类似于复制一个对象,用函数来包装
缺点:1、所有实例都会继承原型上的属性。2、无法实现复用。(新实例属性都是后面添加的)
function Son(obj) {
function F() {}
F.prototype = obj;
return new F()
}
let father =new Father('han',19);
let son = Son(father);
console.log(son.name);
5、寄生继承
就是给原型式继承外面套了个壳子。
优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。
缺点:没用到原型,无法复用。
function Son(obj) {
function F() {}
F.prototype = obj;
return new F()
}
let father = new Father('han',19);
function subType(obj) {
let sub = Son(obj);
sub.name = 'mo';
return sub;
}
let sup = subType(father);
console.log(sup.name);
//或者
function createAnother(original) {
let clone = object(original);// 通过调用函数创建一个新对象
clone.say = function () {
console.log('hi');
};
return clone;
}
let person = {
name:"Han",
friends:['mo','van','trevor']
};
let sub = createAnother(person);
// sub具有person的所有属性和方法,以及say()方法
sub.say(); // 'hi'
6、寄生组合继承(常用)
function content(obj) {
function F() {}
F.pototype = obj;
return F();
}
function Sub() {
Father.call(this)
}
let con = content(Father.prototype);
Sub.prototype = con;
// con.constructor = Sub;
let sub1 = new Sub();
console.log(sub1.age);
//或者
function inheritPrototype(son,father) {
let prototype = Object(father.prototype); // 创建对象
prototype.constructor = son; // 增强对象
son.prototype = prototype; // 赋值对象
}
function son(){
Father.call(this)
}
inheritPrototype(son,Father);
son.prototype.wait = function () {
console.log(this.age);
};
let con = new son();
con.wait();