javascript中的3种继承实现方法
使用object.create实现类式继承
下面是官网的一个例子
//shape - superclass function shape() { this.x = 0; this.y = 0; } shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info("shape moved."); }; // rectangle - subclass function rectangle() { shape.call(this); //call super constructor. } rectangle.prototype = object.create(shape.prototype); var rect = new rectangle(); rect instanceof rectangle //true. rect instanceof shape //true. rect.move(1, 1); //outputs, "shape moved."
此时rectangle原型的constructor指向父类,如需要使用自身的构造,手动指定即可,如下
rectangle.prototype.constructor = rectangle;
使用utilities工具包自带的util.inherites
语法
util.inherits(constructor, superconstructor)
例子
const util = require('util'); const eventemitter = require('events'); function mystream() { eventemitter.call(this); } util.inherits(mystream, eventemitter); mystream.prototype.write = function(data) { this.emit('data', data); } var stream = new mystream(); console.log(stream instanceof eventemitter); // true console.log(mystream.super_ === eventemitter); // true stream.on('data', (data) => { console.log(`received data: "${data}"`); }) stream.write('it works!'); // received data: "it works!"
也很简单的例子,其实源码用了es6的新特性,我们瞅一瞅
exports.inherits = function(ctor, superctor) { if (ctor === undefined || ctor === null) throw new typeerror('the constructor to "inherits" must not be ' + 'null or undefined'); if (superctor === undefined || superctor === null) throw new typeerror('the super constructor to "inherits" must not ' + 'be null or undefined'); if (superctor.prototype === undefined) throw new typeerror('the super constructor to "inherits" must ' + 'have a prototype'); ctor.super_ = superctor; object.setprototypeof(ctor.prototype, superctor.prototype); };
其中object.setprototypeof即为es6新特性,将一个指定的对象的原型设置为另一个对象或者null
语法
object.setprototypeof(obj, prototype)
obj为将要被设置原型的一个对象
prototype为obj新的原型(可以是一个对象或者null).
如果设置成null,即为如下示例
object.setprototypeof({}, null);
感觉setprototypeof真是人如其名啊,专门搞prototype来玩。
那么这个玩意又是如何实现的呢?此时需要借助宗师__proto__
object.setprototypeof = object.setprototypeof || function (obj, proto) { obj.__proto__ = proto; return obj; }
即把proto赋给obj.__proto__就好了。
使用extends关键字
熟悉java的同学应该非常熟悉这个关键字,java中的继承都是靠它实现的。
es6新加入的class关键字是语法糖,本质还是函数.
在下面的例子,定义了一个名为polygon的类,然后定义了一个继承于polygon的类 square。注意到在构造器使用的 super(),supper()只能在构造器中使用,super函数一定要在this可以使用之前调用。
class polygon { constructor(height, width) { this.name = 'polygon'; this.height = height; this.width = width; } } class square extends polygon { constructor(length) { super(length, length); this.name = 'square'; } }
使用关键字后就不用婆婆妈妈各种设置原型了,关键字已经封装好了,很快捷方便。
上一篇: javascript中new关键字详解