Welcome 微信登录

首页 / 脚本样式 / JavaScript / javascript中的3种继承实现方法

使用Object.create实现类式继承
下面是官网的一个例子
//Shape - superclassfunction Shape() { this.x = 0; this.y = 0;}Shape.prototype.move = function(x, y) {this.x += x;this.y += y;console.info("Shape moved.");};// Rectangle - subclassfunction 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); // trueconsole.log(MyStream.super_ === EventEmitter); // truestream.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"; }}
使用关键字后就不用婆婆妈妈各种设置原型了,关键字已经封装好了,很快捷方便。