前端学习笔记-JavaScript继承(一)

75 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

组合式继承

组合 就是两方面都各做一次,缺点是 所谓"两次执行"父类的构造函数

第一次是new实例化 用于创建子类的原型对象 目的是共享方法

第二次是单纯执行 用于将父类的属性赋予子类的实例 目的是拥有属性


父类构造函数 可想象为 形如this.key = val

let parent = function(name) {
      // 父类型的自有属性
      this.name = name;
      this.hobbies = ['tennis','music','photography']
   }

而子类构造函数除了往this上添加属性外,还通过call让自己的this执行父类构造函数 把父类属性加到自己身上

let son = function(name,sex) {
    //构造函数式继承父类属性,这里是第二次调用父类构造函数
    parent.call(this, name); 
    // 添加子类自己的私有属性
    this.sex = sex;
}

在new子类构造函数得到子类实例之前,为了共享原型方法,需要得到一个父类实例 作为子类原型对象

son.prototype = new parent(); 这是首次调用父类构造函数 作为子类原型对象;

son.prototype.constructor = son;并且让这个新的原型对象链接到子类构造函数;

son.prototype.getsex = function () { console.log(this.sex)} 此后可以添加子类自己的方法 请添加图片描述请添加图片描述

梳理:定义子类构造函数(内部是父类call this)->将构造函数原型对象用父类实例替换 ->原型对象的cst指回子类构造函数(此时可以向原型对象上添加共享方法)->创建子类实例(此时父类构造函数将私有属性赋予了子类实例)

优点是子类实例不会修改父类引用属性,缺点是两次执行父类构造函数


原型式继承

场景为 不愿为子类特意创建一个构造函数,于是以现有的对象作为原型浅拷贝得到子类实例(似乎看不出明确父子关系 但是不失为一种继承)

function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}
// 出发点就是不愿意建子类的构造函数,因此也没有把constructor指回去

缺点就是这种浅拷贝 多个实例都可以去修改父类的引用类型属性(可他们以为改的是自己的属性)因此父类的引用属性会被共享