这几天集中注意力看了下nodejs,感觉打开了一扇新的大门,他和熟悉的java语言很不一样,写几行很简单的代码就可以创建服务器连接,当然这背后多亏了chrome的v8 JavaScript引擎。废话有点多,接下来步入正题,看看node中的继承和客户端js有什么不同吧。
一. Javascript客户端继承
我想熟悉js的同学,关于js的继承一定不陌生,实现继承有很多中方式,最常用应该就是借用构造函数继承(call和apply)和原型链继承(prototype)吧,例子如下:
function first(){
var self = this;
this.name = 'first';
}
first.prototype.output = function (){
console.log(this.name);
}
function second(){
first.call(this);
}
second.prototype = new first();
var two = new second();
two.output(); //first
上面的例子中用了组合继承,即对于构造函数的私有数据用call()
方法来继承,对于共享的方法用原型链继承。
二. node中的继承
在node中可以使用util
模块的inherits
来实现继承,util.inherits()
中有两个参数,第一个树子类构造函数,第二个使父类构造函数,例子代码如下(将上面的稍微弄复杂了一点):
//引入util模块
var util = require('util');
function first(){
var self = this;
this.name = 'first';
this.test = function(){
console.log(self);
console.log(self.name);
};
}
first.prototype.output = function (){
console.log(this.name);
}
function second(){
second.super_.call(this); //继承构造函数中的作用域
this.name = 'second';
}
util.inherits(second, first); //继承原型链中的方法
var two = new second();
function third(func){
this.name = 'third';
this.callMethod = func;
}
var three = new third(two.test);
two.output(); //second
two.test(); //second
three.callMethod(); //second
看到输出结果,和客户端js中的继承对比一下就可以很容易的看出,其实second.super_.call(this)
和first.call(this)
完全等价。以及util.inherits(second, first)
和second.prototype = new first()
的功能是等价的(两者还是有区别的,但在这个示例中看起来一样)。
我们可以看一下util.inherits
的实现:
export.inherits = function (ctor, superCtor){
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
}
可以看出,util.inherits
只是继承了父类原型链里的方法,还有super_
只是构造函数的一个属性。而second.prototype = new first();
继承了所有方法。也就是说util.inherits
相当于second.prototype = first.prototype;
。