浅谈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学习笔记之Stream模块
Jan 13 NodeJs
nodeJs链接Mysql做增删改查的简单操作
Feb 04 NodeJs
NodeJs安装npm包一直失败的解决方法
Apr 28 NodeJs
NodeJS、NPM安装配置步骤(windows版本) 以及环境变量详解
May 13 NodeJs
nodejs6下使用koa2框架实例
May 18 NodeJs
nodejs socket实现的服务端和客户端功能示例
Jun 02 NodeJs
nodejs模块学习之connect解析
Jul 05 NodeJs
详解Nodejs 通过 fs.createWriteStream 保存文件
Oct 10 NodeJs
nodejs简单实现TCP服务器端和客户端的聊天功能示例
Jan 04 NodeJs
Nodejs连接mysql并实现增、删、改、查操作的方法详解
Jan 04 NodeJs
NodeJs搭建本地服务器之使用手机访问的实例讲解
May 12 NodeJs
nodeJS与MySQL实现分页数据以及倒序数据
Jun 05 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 Undefined index和Undefined variable的解决方法
2008/03/27 PHP
mysql 查询指定日期时间内sql语句实现原理与代码
2012/12/16 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
2013/06/03 PHP
php列出mysql表所有行和列的方法
2015/03/13 PHP
php实现base64图片上传方式实例代码
2017/02/22 PHP
laravel migrate初学常见错误的解决方法
2017/10/11 PHP
alixixi runcode.asp的代码不错的应用
2007/08/08 Javascript
20行代码实现的一个CSS覆盖率测试脚本
2013/07/07 Javascript
js全屏显示显示代码的三种方法
2013/11/11 Javascript
Javascript学习指南
2014/12/01 Javascript
浅谈JavaScript Array对象
2014/12/29 Javascript
JS实现转动随机数抽奖特效代码
2020/04/16 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
实例代码详解javascript实现窗口抖动及qq窗口抖动
2016/01/04 Javascript
bootstrap为水平排列的表单和内联表单设置可选的图标
2017/02/15 Javascript
HTML中使背景图片自适应浏览器大小实例详解
2017/04/06 Javascript
bootstrap Table服务端处理分页(后台是.net)
2017/10/19 Javascript
js原生方法被覆盖,从新赋值原生的方法
2018/01/02 Javascript
angularJs在多个控制器中共享服务数据的方法
2018/09/30 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
Python解析nginx日志文件
2015/05/11 Python
python生成验证码图片代码分享
2016/01/28 Python
python使用threading获取线程函数返回值的实现方法
2017/11/15 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
Python多进程与服务器并发原理及用法实例分析
2018/08/21 Python
浅谈python多进程共享变量Value的使用tips
2019/07/16 Python
Django框架表单操作实例分析
2019/11/04 Python
Python中Subprocess的不同函数解析
2019/12/10 Python
投标承诺书范本
2014/03/27 职场文书
租房合同协议书
2014/04/09 职场文书
职业生涯规划书结束语
2014/04/15 职场文书
2015年财务个人工作总结范文
2015/05/22 职场文书
仰望星空观后感
2015/06/10 职场文书
六年级作文之预言作文
2019/10/25 职场文书
Python获取江苏疫情实时数据及爬虫分析
2021/08/02 Python