js实现继承的方式

function Human() {
  this.name = 'human';
  this.sleep = function() {
    console.log(this.name + ' sleep');
  };
  this.friends = [1, 2, 3];
}
Human.prototype.age = 18;

原型链继承

原理:将父类的实例作为子类的原型

function Boy() {
  this.name = 'boy';
}
Boy.prototype = new Human();
let b = new Boy();
console.log(b.name); //boy
console.log(b.age); //18
b.sleep(); //boy sleep
console.log(b instanceof Boy); //true
console.log(b instanceof Human); //true
let b2 = new Boy();
b.friends.push(4);
console.log(b.friends, b2.friends); //Array(4) [ 1, 2, 3, 4 ] Array(4) [ 1, 2, 3, 4 ]
  • 实例是子类的实例,也是父类的实例
  • 来自原型对象的所有引用属性被所有实例共享,在一个实例中修改父类属性,其它实例都会变化
  • 创建子类实例时,无法向父类构造函数传参

构造继承

原理:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Boy() {
  Human.call(this);
  this.name = 'boy';
}
let b = new Boy();
console.log(b.age); //undefined
console.log(b instanceof Human); //false
let b2 = new Boy();
b.friends.push(4);
console.log(b.friends, b2.friends); //Array(4) [ 1, 2, 3, 4 ] Array(4) [ 1, 2, 3 ]
  • 子类实例不再共享父类属性
  • 继承时,可以向父类传递参数
  • 可以多继承(call多个父类)
  • 不能继承父类原型上的属性和方法
  • 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

组合继承

Human.prototype.age = 18;
function Boy() {
  Human.call(this);
  this.name = 'boy';
}
Boy.prototype = new Human();
let b = new Boy();
console.log(b.name); //boy
console.log(b.age); //18
b.sleep(); //boy sleep
console.log(b instanceof Boy); //true
console.log(b instanceof Human); //true
let b2 = new Boy();
b.friends.push(4);
console.log(b.friends, b2.friends); //Array(4) [ 1, 2, 3, 4 ] Array(4) [ 1, 2, 3 ]
  • 弥补了原型链继承和构造继承的缺陷
  • 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

寄生组合继承

function Boy() {
  Human.call(this);
  this.name = 'boy';
}
Boy.prototype = Object.create(Human.prototype);
Boy.prototype.constructor = Boy;
  • 弥补了上述方法的缺陷,堪称完美
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值