JavaScript之继承方式

参考资料

(22条消息) JavaScript各种继承,原型继承,构造函数继承,组合继承,寄生组合,ES6继承,我能学会你也可以_不见浅诗的博客-CSDN博客

面试官:Javascript如何实现继承? | web前端面试 - 面试官系列 (vue3js.cn)

JavaScript深入之继承的多种方式和优缺点 · Issue #16 · mqyqingfeng/Blog (github.com)

《JavaScript高级程序设计》

原型链继承

function father(){
    this.age = 21;
    this.person = [1,2,3];
}
father.prototype.getPerson = function(){
    return this.person;
}
function son(){

}
let f = new father();
son.prototype = f;
/* 继承完之后,在定义son自己的prototype */
let SON = new son();
f.person[0] = "fujiaxu";
console.log(SON.getPerson());// fujiaxu

缺点:

子类和父类共享属性,如果这些属性不是基本类型,那么它们之间的修改将会被共享。

构造函数继承

function father(){
    this.age = 21;
    this.person = [1,2,3];
}
function son(){
    father.call(this);
}

let SON = new son();
console.log(SON);

缺点:

不能继承原型上的方法。

组合继承

这是把前面两种继承方式结合起来。

function father() {
    this.age = 21;
    this.person = [1, 2, 3];
}
father.prototype.say = function () {
    return "hello";
};
function son() {
    father.call(this);
}
son.prototype = new father();// 这里为什么是new,需要好好想想
son.prototype.constructor = son;
// 可以写自己的原型上的方法了
let SON = new son();
console.log(SON,SON.say());

缺点:

父类执行了两次

原型式继承

借助Object.create方法实现普通对象的继承

这种继承方式的缺点也很明显,因为Object.create方法实现的是浅拷贝,多个实例的引用类型属性指向相同的内存,存在篡改的可能。

寄生式继承

寄生式继承在上面继承基础上进行优化,利用这个浅拷贝的能力再进行增强,添加一些方法。

function createObj (o) {
    var clone = Object.create(o);
    clone.sayName = function () {
        console.log('hi');
    }
    return clone;
}

寄生组合式继承(最优的继承方式)

这是在组合继承的基础上进行优化,因为组合继承调用了两次构造函数(call 和 new father()),

对于call的调用,这是不可避免的,所以我们要想办法来优化掉new father() 这一步,我们其实只是想要间接访问原型,所以我们就可以使用Object.create(prototype,propertyObject)

function father() {
    this.age = 21;
    this.person = [1, 2, 3];
}
father.prototype.say = function () {
    return "hello";
};
function clone(father,son){
    son.prototype = Object.create(father);
    son.prototype.constructor = son;
}
function son() {
    father.call(this);
}
clone(father,son);
let SON = new son();
console.log(SON);

Object.create()的原理

Object.myCreate = function (proto, propertyObject = undefined) {
  if (propertyObject === null) {
    // 这里没有判断propertyObject是否是原始包装对象
    throw 'TypeError'
  } else {
    function Fn () {} // 空构造函数
    // 该对象是没有构造函数的,或者说,该对象的构造函数式Object
    Fn.prototype = proto
    const obj = new Fn()
    if (propertyObject !== undefined) {
      Object.defineProperties(obj, propertyObject)
    }
    if (proto === null) {
      // 创建一个没有原型对象的对象,Object.create(null)
      obj.__proto__ = null
    }
    return obj
  }
}

ES6 的class

对于ES6的class 也是采用了寄生组合式继承的方式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值