JS类与继承

作者: Quilljou | 来源:发表于2017-07-20 10:25 被阅读59次

一些概念

prototype是构造函数的指针,指向原型对象。讲述的是构造函数和原型对象之间的关系。
__proto__是实例对象的指针,也指向原型对象,讲述的是实例对象和原型对象之间的关系。
因为原型对象也是对象,所以原型对象也有__proto__,指向的是这个原型对象的原型对象,JS实现继承的方式就是根据__proto__指针,在一个对象上查找一个property,会依次在自身对象、原型对象、原型对象的原型对象(就是原型链)。
所以在js中实现继承的关键就是使得一个原型对象的__proto__指针指向某一个(原型)对象。

最后在说一下constructor指针。
constructor是原型对象的的指针,指向构造函数。讲述的是原型对象和构造函数之间的关系。所以和prototype是互逆的一对指针。

《《JavaScript高级程序设计》》第三版讲解原型和继承对于有些基础的人有些拖沓。其中第六章第三节讲解继承的时候也告诉了在JavaScript实现继承的业界默认方式就是借用构造函数和原型继承。

其背后的思路就是使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。

上面这句话总结的很好很全面了。

所以继承包括两个方面,实例属性和原型属性的继承。

继承实例属性最常用的一种方法是上面说到的借用构造函数。

function ParentClass() { // 父类构造函数
}

function ChildrenClass(xx,yy,zz) { // 子类构造函数
  ParentClass.call(this,xx,yy);
  this.zz = zz;
}

继承原型属性的方法就有很多种了。

Object.create

function inherit(C,P) {
  C.prototype = Object.create(P.prototype)
}

inherit(ChildrenClass,ParentClass)

最早老道提出来这种方法叫原型式继承。实现了一个create方法,只不过ES5在语法层面实现了create方法,形成了上面的方法。

function create(o) {
  var F = new Function();
  F.prototype = o;
  return new F();
}

function inherit(C,P) {
  C.prototype = create(P.prototype)
}

inherit(ChildrenClass,ParentClass)

原型式继承之二

function inherit(C,P) {
    var F = new Function();  // 临时构造函数
    F.prototype = P.prototype;
    C.super = P; // 使得子类能够获得对父类的引用
    C.prototype = new F(); // 使得子类的原型对象__proto__指向父类的原型对象,从而实现继承原型方法
    C.prototype.constructor = C; // 使得子类的constructor指针重新指向子类的构造函数
}

inherit(ChildrenClass,ParentClass)

setPrototypeOf

const inherit = function(ctor, superCtor) {

  if (ctor === undefined || ctor === null)
    throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'ctor', 'function');

  if (superCtor === undefined || superCtor === null)
    throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'superCtor', 'function');

  if (superCtor.prototype === undefined) {
    throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'superCtor.prototype',
                               'function');
  }
  ctor.super_ = superCtor;
  Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
};

上面一段代码来自node的util模块的inherits方法。使用了ES6的Object.setPrototypeOf.
其实都ES6了,为什么不直接使用ES6的extends关键字。

ES6

ES6的到来,为JS实现了语言层面的class。其实也只是上面内容的一个语法糖。即使在各种环境都支持ES6和class的情况下,熟悉和了解JS中继承是如何实现的也是很有必要的。
详细的ES6 class讲解可以参考 阮一峰的ES6教程;

相关文章

  • JS类与继承

    一些概念 prototype是构造函数的指针,指向原型对象。讲述的是构造函数和原型对象之间的关系。__proto_...

  • JS继承与类

    继承 概念 通过【某种方式】让一个对象可以访问到另一个对象中的属性和方法,我们把这种方式称之为继承 并不是所谓的x...

  • #js继承

    js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承)类式继承(构造函数间的继承) 类式继承是...

  • JS里的继承

    什么是继承继承的原理如何完成JS的继承? 什么是继承 继承就是子类拥有父类的各种属性和方法那什么是类?这里的JS的...

  • JS继承

    JS中的继承 许多OO语言都支持两种继承方式:接口继承和实现继承; 因为JS中没有类和接口的概念 , 所以JS不支...

  • js继承遇到的小问题

    这两天在看js继承方面,它不像OC那种传统的类继承。js继承方式还是挺多的。比如:原型继承、原型冒充、复制继承 原...

  • js面向对象实现面向对象(二)

    上一篇讲到js实现对类对封装,本篇介绍类的继承,多态。 类的继承 类式继承 类式继承方式是将父类的实例赋在子类的原...

  • JavaScript 10

    js继承的概念 1.通过原型链方式实现继承(对象间的继承) 2.类式继承(构造函数间的继承) 由于js不像Java...

  • JS对象和继承

    JS对象和继承 JS是个无类的语言,因此对于对象构造器(类)和对象的继承就值得我们研究了。本文讲述JS中构造器的表...

  • 请使用Js代码写出一个类继承的模型

    // 请使用Js代码写出一个类继承的模型// 请使用Js代码写出一个类继承的模型,需包含以下实现:// 定...

网友评论

    本文标题:JS类与继承

    本文链接:https://www.haomeiwen.com/subject/gwddkxtx.html