浅谈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实现黑名单中间件设计
Jun 17 NodeJs
nodejs 实现模拟form表单上传文件
Jul 14 NodeJs
nodejs中操作mysql数据库示例
Dec 20 NodeJs
nodejs和php实现图片访问实时处理
Jan 05 NodeJs
NodeJS仿WebApi路由示例
Feb 28 NodeJs
nodejs模块nodemailer基本使用-邮件发送示例(支持附件)
Mar 28 NodeJs
nodeJS(express4.x)+vue(vue-cli)构建前后端分离实例(带跨域)
Jul 05 NodeJs
nodejs中Express与Koa2对比分析
Feb 06 NodeJs
NodeJS搭建HTTP服务器的实现步骤
Oct 12 NodeJs
Nodejs异步流程框架async的方法
Jun 07 NodeJs
nodejs中的异步编程知识点详解
Jan 17 NodeJs
详解nodejs内置模块
May 06 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执行速度全攻略
2006/10/09 PHP
PHP与SQL注入攻击防范小技巧
2011/09/16 PHP
php中curl和file_get_content的区别
2014/05/10 PHP
详解PHP的Yii框架中日志的相关配置及使用
2015/12/08 PHP
PHP版本升级到7.x后wordpress的一些修改及wordpress技巧
2015/12/25 PHP
功能强大的php文件上传类
2016/08/29 PHP
详解Yii2 之 生成 URL 的方法
2017/06/16 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
检测jQuery.js是否已加载的判断代码
2011/05/20 Javascript
brook javascript框架介绍
2011/10/10 Javascript
UpdatePanel和Jquery冲突的解决方法
2013/04/01 Javascript
关于JavaScript中string 的replace
2013/04/12 Javascript
js日期联动示例
2014/05/02 Javascript
javascript实现树形菜单的方法
2015/07/17 Javascript
数据分析软件之FineReport教程:[5]参数界面JS(全)
2015/08/13 Javascript
picLazyLoad 实现图片延时加载(包含背景图片)
2016/07/21 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
2018/04/19 Javascript
微信小程序wx.uploadfile 本地文件转base64的实现代码
2018/06/28 Javascript
Vue.js watch监视属性知识点总结
2019/11/11 Javascript
node静态服务器实现静态读取文件或文件夹
2019/12/03 Javascript
解决vue net :ERR_CONNECTION_REFUSED报错问题
2020/08/13 Javascript
Python使用pygame模块编写俄罗斯方块游戏的代码实例
2015/12/08 Python
教你用Python创建微信聊天机器人
2020/03/31 Python
简单了解python数组的基本操作
2019/11/26 Python
Python使用Tkinter实现滚动抽奖器效果
2020/01/06 Python
Python将二维列表list的数据输出(TXT,Excel)
2020/04/23 Python
Pycharm同步远程服务器调试的方法步骤
2020/11/04 Python
HTML5 贪吃蛇游戏实现思路及源代码
2013/09/03 HTML / CSS
控制工程专业个人求职信
2013/09/25 职场文书
思想汇报格式
2014/01/05 职场文书
怎么写自荐书范文
2014/02/12 职场文书
标准版离职证明书
2014/09/12 职场文书
MySQL入门命令之函数-单行函数-流程控制函数
2021/04/05 MySQL
撤回我也能看到!教你用Python制作微信防撤回脚本
2021/06/11 Python
详解MySQL中timestamp和datetime时区问题导致做DTS遇到的坑
2021/12/06 MySQL