js的继承

2017-05-02  本文已影响0人  任无名F

一、 简单原型继承

function Parent() {
  this.a = 1;
  this.b = [1];
}
Parent.prototype.hello = function() {}

function Child(name) {
  this.name = name;
}
Child.prototype = new Parent(); // 核心
Child.prototype.constructor = Child; // 修正Child的构造函数

let child1 = new Child("child1");
let child2 = new Child("child2");

核心:使用父类的实例来作为子类的原型对象
缺点:1.父类的引用属性会在子类实例中共享 2.创建子类实例时无法给父类构造函数传参

二、 借用构造函数

function Parent(num) {
  this.a = num;
  this.b = [1];
  this.hello2 = function() {} // 此函数会被复制到子类
}
Parent.prototype.hello = function() {} // 此函数不会被复制到子类

function Child(name, num) {
  Parent.call(this, num); // 核心
  this.name = name;
}

let child1 = new Child("child1", 1);
let child2 = new Child("child2", 2);

核心:借用父类的构造函数,将父类的属性复制给子类实例,没有用到原型
优点:解决了简单原型继承的两个问题
缺点:由于没有用到原型,父类复制来的函数无法实现复用

三、 组合继承

function Parent(num) {
  this.a = num;
  this.b = [1];
}
Parent.prototype.hello = function() {}

function Child(name, num) {
  Parent.call(this, num); // 核心
  this.name = name;
}
Child.prototype = new Parent(); // 核心,此处实例化了一个多余的父类对象
Child.prototype.constructor = Child; // 修正Child的构造函数

let child1 = new Child("child1", 1);
let child2 = new Child("child2", 2);

核心:将上述两种方式组合起来使用,将需要复用的函数都放在原型上,将需要复制的属性通过借用构造函数复制给子类实例
优点:解决了所有问题
缺点:实例化了一个“多余”的父类对象

四、 寄生组合继承

function Parent(num) {
  this.a = num;
  this.b = [1];
}
Parent.prototype.hello = function() {}

function Child(name, num) {
  Parent.call(this, num); // 核心
  this.name = name;
}
function extend(child, parent) {
  let F = function() {};
  F.prototype = parent.prototype;
  child.prototype = new F(); // 核心,用一个空函数来避免实例化属性的浪费
  child.prototype.constructor = child; // 修正构造函数
}
extend(Child, Parent); // 核心

let child1 = new Child("child1", 1);
let child2 = new Child("child2", 2);

核心:与组合继承基本一样,只是针对多余的实例化进行了优化
优点:解决了所有问题
缺点:比较麻烦……

上一篇 下一篇

猜你喜欢

热点阅读