Skip to content

讲讲ES5中的继承吧 #31

Description

@su-Pro

继承

什么是面向对象?JavaScript是面向对象语言吗?

面向对象语言都有一个标志就是类的概念,通过类可以创建多个对象具有相同方法和属性。在JavaScript中没有类的概念,因此他的继承和面向对象语言不太一样,是基于原型对象的一种继承方案。

原型链继承

利用原型让一个引用类型继承另外一个引用类型的方法和属性,通过让待继承的引用类型的原型对象指向另一个类型的实例。

存在的问题:

  • 引用值共享问题
  • 创建子类时,无法向其超类进行参数传递
  • 不能用对象字面量语法向原型中添加属性(改变原型指针,会切断原型链)
function Child() {
  this.name = ['1','2']
}
function Son () {}
Son.prototype = new Child();
var son1 = new Son();// 无法向父类传递参数
var son2 = new Son()
son1.name.push('3')
//son2.name 也会跟着改变

借用构造函数继承

子类的构造函数内部调用父类的构造函数,能够解决传递参数的问题。

  • 不存在原型继承后,函数无法复用
  • 超类原型中的方法无法被继承,所有类型只能使用构造函数中的方法
function Parent() {
  this.name = [‘foo’,’bar’];
  this.funcLog = function () {
    console.log(‘能够使用’);
  }
}
//想要继承自Father,通过借用构造函数形式,将this绑定到
function Child(...args) {
  Father.apply(this,args)
}

组合继承

使用原型式继承实现对原型中属性和方法的继承,使用构造函数实现对实例属性的继承。

将原型链继承和借用构造函数融为一体,能够实现向父类传递参数并且避免了引用值的问题,是最常用的一种继承方案。

function Parent(name) {
  this.name = [‘foo’,’bar’];
}
Parent.prototype.func = function () {
  console.log(‘继承方法成功’);
}
function Child(…args) {
  Parent.call(this,args)
}
Child.prototype = new Parent();
// 由于原型对象被重写,需要将constructor指针归位
Child.prototype.constructor = Child;

原型式继承

借助原型式继承可以对已有的对象创建一个新对象(继承自已有的对象),这种实现继承的方法不需要创建构造函数。

前提是你必须有一个对象作为另外一个对象的继承基础,ES5对该模式封装为:Object.create(对象,属性描述符)

问题:

  • 和原型链继承一样的问题,对引用值的共享
function Parent(name) {
  this.name = [‘foo’,’bar’];
}
Parent.prototype.func = function () {
  console.log(‘继承成功’);
}
function myCreate (o) {
  // 中转函数
  function F () {}
  F.prototype = o;
  return new F();
}

寄生组合继承(圣杯继承)

最完美的一种继承方案,需要注意的是重写原型后,需要将constructor 进行归位操作。

问题:

  • 调用两次超类构造函数
function _extend (sub,super) {
  var _prototype = _create(super);
  _prototype.constructor = sub;
  sub.prototype = _prototype;

  function _create(super) {
    function F () {}
    F.prototype = super.prototype;
    return new F ()
  }
}

具体内容查阅 高程

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions