浅谈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 05 NodeJs
使用Nodejs开发微信公众号后台服务实例
Sep 03 NodeJs
nodejs中操作mysql数据库示例
Dec 20 NodeJs
NodeJS使用jQuery选择器操作DOM
Feb 13 NodeJs
nodejs爬虫抓取数据之编码问题
Jul 03 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 NodeJs
使用npm安装最新版本nodejs
Jan 18 NodeJs
nodejs中密码加密处理操作详解
Mar 20 NodeJs
nodejs中request库使用HTTPS代理的方法
Apr 30 NodeJs
nodejs的安装使用与npm的介绍
Sep 11 NodeJs
详解nodejs内置模块
May 06 NodeJs
NodeJs内存占用过高的排查实战记录
May 10 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
给多个地址发邮件的类
2006/10/09 PHP
php导入csv文件碰到乱码问题的解决方法
2014/02/10 PHP
php中使用gd库实现下载网页中所有图片
2015/05/12 PHP
PHP如何将log信息写入服务器中的log文件
2015/07/29 PHP
PHP7.0安装笔记整理
2015/08/28 PHP
zend framework重定向方法小结
2016/05/28 PHP
Laravel 5.3 学习笔记之 配置
2016/08/28 PHP
Ajax实现对静态页面的文章访问统计功能示例
2016/10/10 PHP
js基于qrcode.js生成二维码的方法【附demo插件源码下载】
2016/12/28 PHP
javascript 哈希表(hashtable)的简单实现
2010/01/20 Javascript
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
javascript作用域容易记错的两个地方分析
2012/06/22 Javascript
JQuery文字列表向上滚动的代码
2013/11/13 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
js实现的倒计时按钮实例
2015/06/24 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
2015/08/27 Javascript
浅析jquery数组删除指定元素的方法:grep()
2016/05/19 Javascript
整理关于Bootstrap列表组的慕课笔记
2017/03/29 Javascript
Node.js使用orm2进行update操作时关联字段无法修改的解决方法
2017/06/13 Javascript
jQuery 实现双击编辑表格功能
2017/06/19 jQuery
react中的ajax封装实例详解
2017/10/17 Javascript
Dropify.js图片宽高自适应的方法
2017/11/27 Javascript
Layui给switch添加响应事件的例子
2019/09/03 Javascript
python的即时标记项目练习笔记
2014/09/18 Python
Python中处理字符串之isalpha()方法的使用
2015/05/18 Python
Python 通过pip安装Django详细介绍
2017/04/28 Python
python 换位密码算法的实例详解
2017/07/19 Python
利用Anaconda简单安装scrapy框架的方法
2018/06/13 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
2019/08/09 Python
pytorch下使用LSTM神经网络写诗实例
2020/01/14 Python
解决Tensorboard 不显示计算图graph的问题
2020/02/15 Python
Python如何在循环内使用list.remove()
2020/06/01 Python
清洁工岗位职责
2014/01/29 职场文书
作文批改评语大全
2014/04/23 职场文书
经理岗位职责
2015/02/02 职场文书
公务员年度个人总结
2015/02/12 职场文书