浅谈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 npm install全局安装和本地安装的区别
Jun 05 NodeJs
nodejs npm package.json中文文档
Sep 04 NodeJs
nodejs实现发出蜂鸣声音(系统报警声)的方法
Jan 18 NodeJs
nodejs构建本地web测试服务器 如何解决访问静态资源问题
Jul 14 NodeJs
nodejs 搭建简易服务器的图文教程(推荐)
Jul 18 NodeJs
nodejs读取并去重excel文件
Apr 22 NodeJs
Nodejs 和 Electron ubuntu下快速安装过程
May 04 NodeJs
nodejs中方法和模块用法示例
Dec 24 NodeJs
NodeJs实现简易WEB上传下载服务器
Aug 10 NodeJs
Nodejs libuv运行原理详解
Aug 21 NodeJs
nodejs实现百度舆情接口应用示例
Feb 07 NodeJs
nodejs+express最简易的连接数据库的方法
Dec 23 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
php xml-rpc远程调用
2008/12/19 PHP
详解在YII2框架中使用UEditor编辑器发布文章
2018/11/02 PHP
php5对象复制、clone、浅复制与深复制实例详解
2019/08/14 PHP
laravel-admin解决表单select联动时,编辑默认没选上的问题
2019/09/30 PHP
Thinkphp 框架扩展之行为扩展原理与实现方法分析
2020/04/23 PHP
用dtree实现树形菜单 dtree使用说明
2011/10/17 Javascript
简单的代码实现jquery定时器
2013/11/17 Javascript
使用不同的方法结合/合并两个JS数组
2014/09/18 Javascript
js基于cookie方式记住返回页面用法示例
2016/05/27 Javascript
AngularJS中update两次出现$promise属性无法识别的解决方法
2017/01/05 Javascript
nodejs实现大文件(在线视频)的读取
2020/10/16 NodeJs
Angular4.0中引入laydate.js日期插件的方法教程
2017/12/25 Javascript
Vue 项目中遇到的跨域问题及解决方法(后台php)
2018/03/28 Javascript
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
ES6知识点整理之函数数组参数的默认值及其解构应用示例
2019/04/17 Javascript
js实现聊天对话框
2020/02/08 Javascript
vue video和vue-video-player实现视频铺满教程
2020/10/30 Javascript
用javascript实现倒计时效果
2021/02/09 Javascript
[00:55]2015国际邀请赛中国区预选赛5月23日——28日约战上海
2015/05/25 DOTA
[06:59]DOTA2-DPC中国联赛3月7日Recap集锦
2021/03/11 DOTA
解决Python中字符串和数字拼接报错的方法
2016/10/23 Python
Python中matplotlib中文乱码解决办法
2017/05/12 Python
python将txt文件读取为字典的示例
2018/12/22 Python
python系统指定文件的查找只输出目录下所有文件及文件夹
2020/01/19 Python
Python表达式的优先级详解
2020/02/18 Python
jupyter notebook 重装教程
2020/04/16 Python
Java爬虫技术框架之Heritrix框架详解
2020/07/22 Python
python 利用百度API识别图片文字(多线程版)
2020/12/14 Python
Ted Baker英国官网:男士和女士服装及配件
2017/03/13 全球购物
销售总经理岗位职责
2014/03/15 职场文书
优质服务口号
2014/06/11 职场文书
小学国旗下的演讲稿
2014/08/28 职场文书
离婚协议书范本(2014版)
2014/09/28 职场文书
灵山大佛导游词
2015/02/04 职场文书
python 自动刷新网页的两种方法
2021/04/20 Python
python前后端自定义分页器
2022/04/13 Python