浅谈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 相关文章推荐
nodejs中exports与module.exports的区别详细介绍
Jan 14 NodeJs
nodejs 整合kindEditor实现图片上传
Feb 03 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
利用nodejs监控文件变化并使用sftp上传到服务器
Feb 18 NodeJs
nodejs学习笔记之路由
Mar 27 NodeJs
Nodejs搭建wss服务器教程
May 24 NodeJs
详解nodeJS之路径PATH模块
May 31 NodeJs
Nodejs 和 Electron ubuntu下快速安装过程
May 04 NodeJs
修改Nodejs内置的npm默认配置路径方法
May 13 NodeJs
通过实例了解Nodejs模块系统及require机制
Jul 16 NodeJs
一文秒懂nodejs中的异步编程
Jan 28 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
神族 PROTOSS 概述
2020/03/14 星际争霸
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
phpstorm 正则匹配删除空行、注释行(替换注释行为空行)
2018/01/21 PHP
PHP单元测试框架PHPUnit用法详解
2019/01/23 PHP
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
关于window.pageYOffset和document.documentElement.scrollTop
2011/04/05 Javascript
jquery formValidator插件ajax验证 内容不做任何修改再离开提示错误的bug解决方法
2013/01/04 Javascript
js substr支持中文截取函数代码(中文是双字节)
2013/04/17 Javascript
利用jquery写的左右轮播图特效
2014/02/12 Javascript
在Ubuntu上安装最新版本的Node.js
2014/07/14 Javascript
Bootstrap项目实战之子栏目资讯内容
2016/04/25 Javascript
JavaScript中自带的 reduce()方法使用示例详解
2016/08/10 Javascript
PHP实现本地图片上传和验证功能
2017/02/27 Javascript
jQuery回调方法使用示例
2017/06/26 jQuery
JavaScript的六种继承方式(推荐)
2017/06/26 Javascript
label+input实现按钮开关切换效果的实例
2017/08/16 Javascript
JS运动特效之同时运动实现方法分析
2018/01/24 Javascript
使用elementUI实现将图片上传到本地的示例
2018/09/04 Javascript
jQuery实现购物车的总价计算和总价传值功能
2018/11/28 jQuery
JavaScript中将值转换为字符串的五种方法总结
2019/06/06 Javascript
[01:11]steam端dota2实名认证操作流程视频
2021/03/11 DOTA
使用Python判断质数(素数)的简单方法讲解
2016/05/05 Python
Python实现获取命令行输出结果的方法
2017/06/10 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
Python3连接SQLServer、Oracle、MySql的方法
2018/06/28 Python
用python打印1~20的整数实例讲解
2019/07/01 Python
python二维图制作的实例代码
2020/12/03 Python
Python自动化测试基础必备知识点总结
2021/02/07 Python
Python读写Excel表格的方法
2021/03/02 Python
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
英国健康和美容技术产品购物网站:CurrentBody
2019/07/17 全球购物
大学生社会实践自我鉴定
2014/03/24 职场文书
学生安全承诺书
2014/05/22 职场文书
2014年党员个人剖析材料
2014/10/08 职场文书
学子宴致辞大全
2015/07/27 职场文书
2016年先进教师个人事迹材料
2016/02/26 职场文书