浅谈nodejs中的类定义和继承的套路
javascript是一门极其灵活的语言。
灵活到你无法忍受!
我个人喜欢强类型的语言,例如c/c++,c#等。
但是js代表着未来,所以需要学习。
js中类定义以及继承有n多种方式,现在来学习一下nodejs类定义以及继承的固定套路。
套路1. 在构造函数(constructor)中总是使用instanceof操作符:
function base() { if (!(this instanceof base)) { return new base(); } }
上述代码的含义就是: 如果base这个函数调用时没有使用new操作符,则会自动调用new操作符,返回base的实例
套路2. 所有成员变量定义在构造函数(constructor)中
function base() { if (!(this instanceof base)) { return new base(); } //开始成员变量定义 this.classname = "base"; }
套路3. 所有的成员方法以函数表达式方式定义在原型(prototype)中【为什么要这样,其原因在套路4中的inherits源码注释中】
base.prototype.printclassname = function(){ console.log(this.classname); }
调用如下:
var base = base(); //不使用new操作符,直接进行函数调用,自动调用new操作符 console.log(base.classname); base.printclassname();
套路4. 使用util.inherits(子类,父类)进行原型(prototype)继承
先来看一下inherits的源码:
var inherits = function(ctor, superctor) { //严格相等测试:undefined/null //子类构造函数必须存在 if (ctor === undefined || ctor === null) throw new typeerror('the constructor to "inherits" must not be ' + 'null or undefined'); //严格相等测试:undefined/null //父类构造函数必须存在 if (superctor === undefined || superctor === null) throw new typeerror('the super constructor to "inherits" must not ' + 'be null or undefined'); //要点: 如果要继承的话,父类必须要有prototype对象 //这也是为什么将所有成员方法都定义在prototype对象中!!! if (superctor.prototype === undefined) throw new typeerror('the super constructor to "inherits" must ' + 'have a prototype'); //让子类构造函数对象增加一个super_指针,指向父类,这样就形成继承链 ctor.super_ = superctor; //调用object.setprototypeof(子类的prototype,父类的prototype) object.setprototypeof(ctor.prototype, superctor.prototype); };
object.setprototypeof : 该链接可以了解一下setprototypeof方法,非常简单,其polyfill如下:
// 仅适用于chrome和firefox,在ie中不工作: object.setprototypeof = object.setprototypeof || function (obj, proto) { obj.__proto__ = proto; return obj; }
我们来测试一下继承。
先定义子类
function child() { //老样子,套路1 if (!(this instanceof child)) { return new child(); } }
然后根据套路4, 调用inherits函数进行原型继承
//注意,inherits调用不在构造函数,也不在原型对象,而是全局调用 inherits(child, base);
最后我们调用一下child的printclassname方法,该方法在基类原型对象中实现。
子类调用基类函数-undefined.png
出现错误,child.printclassname()后输出undefined!
为什么呢?
套路5. 子类的构造函数中使用 父类.call(this),实现父类构造函数中的成员变量继承
function child() { //老样子,套路1 if (!(this instanceof child)) { return new child(); } //增加这句话,在调用printclassname就能正常的输出base字符串 base.call(this); //如果要更新基类的成员变量,请在base.call(this)之后! this._classname = "child"; //调用printclassname就能正常的输出child字符串 }
由此可见,nodejs中的继承需要:
在构造函数中调用 父类.call(this),实现父类成员变量的继承
全局调用inherits(子类,父类) 进行父类成员函数的继承
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 将list转换为json失败的原因
下一篇: Extjs实现进度条的两种便捷方式