浅谈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获取本机内网和外网ip地址的实现代码
Jun 01 NodeJs
我的NodeJs学习小结(一)
Jul 06 NodeJs
基于NodeJS的前后端分离的思考与实践(二)模版探索
Sep 26 NodeJs
NodeJS Web应用监听sock文件实例
Feb 18 NodeJs
nodejs multer实现文件上传与下载
May 10 NodeJs
Nodejs之TCP服务端与客户端聊天程序详解
Jul 07 NodeJs
nodejs中安装ghost出错的原因及解决方法
Oct 23 NodeJs
关于Mac下安装nodejs、npm和cnpm的教程
Apr 11 NodeJs
nodejs高大上的部署方式(PM2)
Sep 11 NodeJs
通过Nodejs搭建网站简单实现注册登录流程
Jun 14 NodeJs
nodejs各种姿势断点调试的方法
Jun 18 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
一个图形显示IP的PHP程序代码
2007/10/19 PHP
探寻PHP脚本不报错的原因
2014/06/12 PHP
php开启与关闭错误提示适用于没有修改php.ini的权限
2014/10/16 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
2016/03/16 PHP
如何取得中文输入的真实长度?
2006/06/24 Javascript
jQuery对象与DOM对象之间的转换方法
2010/04/15 Javascript
javascript Array.prototype.slice的使用示例
2013/11/14 Javascript
关于onchange事件在IE和FF下的表现及解决方法
2014/03/08 Javascript
Javascript判断文件是否存在(客户端/服务器端)
2014/09/16 Javascript
BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
2014/10/29 Javascript
分享几种比较简单实用的JavaScript tabel切换
2015/12/31 Javascript
基于JavaScript判断浏览器到底是关闭还是刷新(超准确)
2016/02/01 Javascript
javascript检查某个元素在数组中的索引值
2016/03/30 Javascript
JS动态改变浏览器标题的方法
2016/04/06 Javascript
jQuery中的通配符选择器使用总结
2016/05/30 Javascript
对javascript继承的理解
2016/10/11 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
新手快速入门JavaScript装饰者模式与AOP
2019/06/24 Javascript
vue-cli3配置与跨域处理方法
2019/08/17 Javascript
React.js组件实现拖拽排序组件功能过程解析
2020/04/27 Javascript
[03:01]完美世界DOTA2联赛PWL S2 集锦第二期
2020/12/03 DOTA
python正则分组的应用
2013/11/10 Python
Python使用htpasswd实现基本认证授权的例子
2014/06/10 Python
python实现逻辑回归的方法示例
2017/05/02 Python
Python Django框架防御CSRF攻击的方法分析
2019/10/18 Python
python算的上脚本语言吗
2020/06/22 Python
CSS3 text shadow字体阴影效果
2016/01/08 HTML / CSS
GAP美国官网:美国休闲时尚品牌
2016/08/26 全球购物
澳大利亚在线百货商店:Real Smart
2017/08/13 全球购物
恒华伟业笔试面试题
2015/02/26 面试题
毕业生的自我鉴定
2013/10/29 职场文书
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
教师作风整顿个人剖析材料
2014/10/10 职场文书
商务信函英语问候语
2015/11/10 职场文书
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
2021/05/26 Servers