浅谈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教程之制作一个简单的文章发布系统
Nov 21 NodeJs
轻松创建nodejs服务器(10):处理上传图片
Dec 18 NodeJs
浅谈Nodejs观察者模式
Oct 13 NodeJs
nodejs中使用HTTP分块响应和定时器示例代码
Mar 19 NodeJs
nodeJS服务器的创建和重新启动的实现方法
May 12 NodeJs
Linux Centos7.2下安装nodejs&npm配置全局路径的教程
May 15 NodeJs
Nodejs使用Mongodb存储与提供后端CRD服务详解
Sep 04 NodeJs
详解从NodeJS搭建中间层再谈前后端分离
Nov 13 NodeJs
nodejs 使用http进行post或get请求的实例(携带cookie)
Jan 03 NodeJs
Nodejs对postgresql基本操作的封装方法
Feb 20 NodeJs
typescript nodejs 依赖注入实现方法代码详解
Jul 21 NodeJs
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
May 30 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 第三节 变量介绍
2012/04/28 PHP
PHP中session变量的销毁
2014/02/27 PHP
Laravel 5框架学习之环境与配置
2015/04/08 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
Javascript解决常见浏览器兼容问题的12种方法
2010/01/04 Javascript
js中的值类型和引用类型小结 文字说明与实例
2010/12/12 Javascript
Javascript和HTML5利用canvas构建Web五子棋游戏实现算法
2013/07/17 Javascript
json格式的时间显示为正常年月日的方法
2013/09/08 Javascript
javascript中slice(),splice(),split(),substring(),substr()使用方法
2015/03/13 Javascript
基于jquery animate操作css样式属性小结
2015/11/27 Javascript
JS使用post提交的两种方式
2015/12/03 Javascript
location.hash保存页面状态的技巧
2016/04/28 Javascript
用js动态添加html元素,以及属性的简单实例
2016/07/19 Javascript
jquery css实现邮箱自动补全
2016/11/14 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
原生js jquery ajax请求以及jsonp的调用方法
2017/08/04 jQuery
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
2017/09/20 jQuery
jQuery简单实现向列表动态添加新元素的方法示例
2017/12/25 jQuery
vue的列表交错过渡实现代码示例
2019/05/05 Javascript
8个非常实用的Vue自定义指令
2020/12/15 Vue.js
Python生成随机MAC地址
2015/03/10 Python
用Python实现协同过滤的教程
2015/04/08 Python
使用python绘制常用的图表
2016/08/27 Python
Python+微信接口实现运维报警
2016/08/27 Python
python实现各种插值法(数值分析)
2019/07/30 Python
python文件处理fileinput使用方法详解
2020/01/02 Python
Python开发之pip安装及使用方法详解
2020/02/21 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
英国最大的手表网站:The Watch Hut
2017/03/31 全球购物
机电专业体育教师求职信
2013/09/21 职场文书
2014年助理工程师工作总结
2014/11/14 职场文书
在职证明格式样本
2015/06/15 职场文书
2015年大学生暑期实习报告
2015/07/13 职场文书
领导干部学习心得体会
2016/01/23 职场文书
使用Redis实现秒杀功能的简单方法
2021/05/08 Redis