浅谈nodejs中的类定义和继承的套路


Posted in NodeJs onJuly 26, 2017

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方法,该方法在基类原型对象中实现。

浅谈nodejs中的类定义和继承的套路

子类调用基类函数-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字符串
}

Function.prototype.call()

由此可见,nodejs中的继承需要:

在构造函数中调用 父类.call(this),实现父类成员变量的继承

全局调用inherits(子类,父类) 进行父类成员函数的继承

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
Windows系统中安装nodejs图文教程
Feb 28 NodeJs
详解NodeJs支付宝移动支付签名及验签
Jan 06 NodeJs
用nodejs搭建websocket服务器
Jan 23 NodeJs
详解nodejs微信公众号开发——5.素材管理接口
Apr 11 NodeJs
nodejs中sleep功能实现暂停几秒的方法
Jul 12 NodeJs
nodejs动态创建二维码的方法
Aug 12 NodeJs
nodejs创建简易web服务器与文件读写的实例
Sep 07 NodeJs
详解NODEJS的http实现
Jan 04 NodeJs
Mac下通过brew安装指定版本的nodejs教程
May 17 NodeJs
nodejs 使用 js 模块的方法实例详解
Dec 04 NodeJs
Nodejs对postgresql基本操作的封装方法
Feb 20 NodeJs
nodejs处理tcp连接的核心流程
Feb 26 NodeJs
nodejs之get/post请求的几种方式小结
Jul 26 #NodeJs
nodejs前端自动化构建环境的搭建
Jul 26 #NodeJs
nodejs body-parser 解析post数据实例
Jul 26 #NodeJs
深入解析nodejs HTTP服务
Jul 25 #NodeJs
NodeJS使用七牛云存储上传文件的方法
Jul 24 #NodeJs
nodejs 搭建简易服务器的图文教程(推荐)
Jul 18 #NodeJs
nodejs密码加密中生成随机数的实例代码
Jul 17 #NodeJs
You might like
MySql数据库查询结果用表格输出PHP代码示例
2015/03/20 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2021/03/09 PHP
求解开jscript.encode代码的asp函数
2007/02/28 Javascript
jQuery TextBox自动完成条
2009/07/22 Javascript
使用console进行性能测试
2015/04/27 Javascript
jQuery中的each()详细介绍(推荐)
2016/05/25 Javascript
EasyUI布局 高度自适应
2016/06/04 Javascript
项目实践一图片上传之form表单还是base64前端图片压缩(前端图片压缩)
2016/07/28 Javascript
js以分隔符分隔数组中的元素并转换为字符串的方法
2016/11/16 Javascript
详解基于javascript实现的苹果系统底部菜单
2016/12/02 Javascript
解决URL地址中的中文乱码问题的办法
2017/02/10 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
2017/02/22 Javascript
javascript实现对话框功能警告(alert 消息对话框)确认(confirm 消息对话框)
2019/05/07 Javascript
vue+element实现表单校验功能
2019/05/20 Javascript
Vue移动端项目实现使用手机预览调试操作
2020/07/18 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
在vue中使用jsonp进行跨域请求接口操作
2020/10/29 Javascript
Python最长公共子串算法实例
2015/03/07 Python
Python cookbook(数据结构与算法)保存最后N个元素的方法
2018/02/13 Python
python第三方库学习笔记
2020/02/07 Python
Too Faced官网:美国知名彩妆品牌
2017/03/07 全球购物
娱乐地球:Entertainment Earth
2020/01/08 全球购物
澳大利亚美容产品及化妆品在线:Activeskin
2020/06/03 全球购物
火山动力Java笔试题
2014/06/26 面试题
岗位职责的含义
2013/11/17 职场文书
实习生的自我评价
2014/01/08 职场文书
管理专员自荐信
2014/01/26 职场文书
药学专业学生的自我评价分享
2014/02/06 职场文书
党的群众路线查摆剖析材料
2014/10/10 职场文书
单位租房协议书范本
2014/12/04 职场文书
导游词怎么写
2015/02/04 职场文书
医学生自荐信范文
2015/03/05 职场文书
2015年国庆节标语大全
2015/07/30 职场文书
mysql中整数数据类型tinyint详解
2021/12/06 MySQL
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
2022/04/24 Java/Android
win10如何更改appdata文件夹的默认位置?
2022/07/15 数码科技