上一篇博客说到了node.js继承events类实现事件发射和事件绑定函数,其中我们实现了一个公用基类 _base ,然后在模型中差异化的定义了各种业务需要的模型并继承 _base 公共基类.但是其中的继承是一笔带过,今天详细的说下node.js中继承.

var events=require('events');
var util=require('util');
 
function _base(){
    this.emitter=new events.EventEmitter(this);
};
 
util.inherits(_base,events.EventEmitter); //继承
 
_base.prototype.onEvent=function(eventName,callback){
    this.emitter.on(eventName,callback);
}
 
_base.prototype.emitEvent=function(eventName,arg){
    this.emitter.emit(eventName,arg);
}
 
module.exports=_base;

util 包介绍:

node.js中的util核心包是node.js自带的核心代码,其完全用javascript代码实现,里面实现了一些常用的工具方法.

其中,我们今天要说的继承方法 inherites 就是util 核心包实现的一个api

util.inherits :

util.inherits(constructor, superConstructor)

此方法有2个参数: 此方法参数针对的都是构造函数

constructor : 构造函数

superConstructor: 父类构造函数

分析最上面的代码:

var events=require('events');
var util=require('util');

node.js 核心代码都包含上面的2个包,直接 require 引用即可

接下来是构造函数:

function _base(){
    this.emitter=new events.EventEmitter(this);
};

此构造函数里定义了一个私有变量 emitter ,细心的人应该发现此私有变量在下面的方法中用到了,为什么会这样,我们会再下一篇博客中来分析原型对象为何能共享构造函数中的私有变量.(此篇略过)

再下来是继承语法:

util.inherits(_base,events.EventEmitter); //继承

inherits 把2个构造函数传入进去到底做了什么?

我们来看下 inherits 的源码:

exports.inherits = function(ctor, superCtor) {
 ctor.super_ = superCtor;
 ctor.prototype = Object.create(superCtor.prototype, {
 constructor: {
  value: ctor,
  enumerable: false,
  writable: true,
  configurable: true
 }
 });
};

在上面的代码中 ctor 想要继承 superCtor ,我们姑且把 ctor 称作子类, superCtor 称作父类.

ctor.super_= superCtor;

super_属性是子类继承父类时构造函数要写入的一个属性值.

ctor.prototype=Object.create(superCtor,prototype,{.....});

我们可以看到源码中子类原型指像父类原型对象.

当通过 new关键字创建子类对象时,子类原型对象上的属性都将会复制一份到子类对象中.就这样达到了继承的效果.

上面子类原型被Object.create() 方法赋值,那么我们再来看下 Object,create 是何方神圣.

Object.create

Object.create(proto [, propertiesObject ])

作用:

通过指定的原型对象和属性创建一个新的对象.

proto 就是原型对象,

propertiesObject 就是指定的原型对象的属性,可选属性(非必填),如何理解这个参数?  它有4个属性,如下:

var myBlog = Object.create({}, {'blog':{'value':'yijiebuyi', 'writable': false, 'enumerable': false, 'configurable': false}});

我们定义了一个 myBlog 对象引用

通过 Object,create 来赋值, 原型对象为 {}

propertiesObject 是对应的

{'blog':{'value':'yijiebuyi', 'writable': false, 'enumerable': false, 'configurable': false}}
value: 表示blog 的属性值;
writable: 表示blog 的属性值是否可写;[默认为: false]
enumerable: 表示属性blog 是否可以被枚举;[默认为: false]
configurable: 表示属性blog 是否可以被配置,例如 对obj.a做 delete操作是否允许;[默认为: false]

所以:create 函数实现原理就是 指定一个原型对象 obj ,然后把指定属性(及属性的配置)指到 原型对象下.

那么最后得到的 myblog 对象是这样的 {blog: "yijiebuyi"}

那我们知道了 util 中的 inherits 方法内部主要是调用了 Object.create来创建了一个新对象,新对象是基于父类原型对象 superCtor.prototype

另外一个属性是 constructor ,构造函数new出来的对象都有此属性,此属性值是指向了构造函数的引用.我们一般通过此属性可以得知这个对象是被谁new出来的.

{
 constructor: {
  value: ctor,
  enumerable: false,
  writable: true,
  configurable: true
 }
 }

如上代码就是定义了 contructor 属性,它的值是 ctor ,ctor是什么? 别忘了我们的初衷, ctor正是 inherits 函数传入的第一个参数,就是子类引用.

所以这个 create 函数创建了一个以父类原型对象为基础的新对象,同时把 contructor 属性指向子类构造函数.

node.js 下使用 util.inherits 来实现继承的更多相关文章

  1. Node.js 常用工具 util

    util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足. util.inherits util.inherits(constructor ...

  2. Node.js 常用工具util

    util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足. util.inherits util.inherits(constructor ...

  3. Node.js 常用工具util包

    Node.js 常用工具 util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足. util.isError(obj); util.is ...

  4. 31.Node.js 常用工具 util

    转自:http://www.runoob.com/nodejs/nodejs-module-system.html util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaS ...

  5. node.js 下依赖Express 实现post 4种方式提交参数

    上面这个图好有意思啊,哈哈, v8威武啊.... 在2014年的最后一天和大家分享关于node.js 如何提交4种格式的post数据. 上上一篇说到了关于http协议里定义的4种常见数据的post方法 ...

  6. npm 是node.js下带的一个包管理工具

    npm 是node.js下带的一个包管理工具          npm install -g webpack webpack是一个打包工具 gulp是一个基于流的构建工具,相对其他构件工具来说,更简洁 ...

  7. node.js下操作cookie

    cookie,又是cookie.工作中与cookie打交道很多次,不过时间跨度也大,每总结多一次,就加深了解多一点. cookie,一定是放在浏览器中的,用于浏览器保存一些小额度的内容.每次我们去访问 ...

  8. node.js下使用RSA加密事例(windows)

    1.安装openss 直接下载window下的安装包 http://houjixin.blog.163.com/blog/static/3562841020144143494875/ 以我发博文现在的 ...

  9. Node.js下的Hello World

    Node.js技术现在可谓是如火如荼,前后端都统一为Javascript的体验绝对是受到了很多人的青睐,我都后悔以前没抽时间好好学一学Javascript了. 首先,我来介绍一下Node.js.本人实 ...

随机推荐

  1. 报错:The valid characters are defined in RFC 7230 and RFC 3986

    访问 spring boot controller时,报错:The valid characters are defined in RFC 7230 and RFC 3986 1.特殊符号 @Spri ...

  2. php和c++自带的排序算法

    PHP的 sort() 排序算法与 C++的 sort() 排序算法均为不稳定的排序算法,也就是说,两个值相同的数经过排序后,两者比较过程中还进行了交换位置,后期开发应主要这个问题

  3. Zookeeper如何正确设置和获取watcher

    Watcher 设置是开发中最常见的,需要搞清楚watcher的一些基本特征,对于exists.getdata.getchild对于节点的不同操作会收到不同的 watcher信息   state=-1 ...

  4. /proc/sys/net/ipv4/下各参数含义

    net.ipv4.tcp_tw_reuse = 0 表示开启重用.允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 net.ipv4.tcp_tw_recycle = ...

  5. [转]Tetris(俄罗斯方块) in jQuery/JavaScript!

    本文转自:http://pwwang.com/2009/10/25/tetris-in-jquery-javascript/ All in jQuery/JavaScript + HTML! Demo ...

  6. OpenStack Weekly Rank 2015.08.24

    Module Reviews Drafted Blueprints Completed Blueprints Filed Bugs Resolved Bugs Cinder 5 1 1 6 13 Sw ...

  7. ecshop点击订购、加入按钮没反应的解决方法

    今天做ecshop站的时候,测试数据,发现点击订购.加入按钮都没反应,网上搜索,有些人说是修改了common.js,我将原始版本复原也没反映.后来重新安装ecshop,仔细研究发现,原来头部文件pag ...

  8. HDU 1281——棋盘游戏——————【最大匹配、枚举删点、邻接表方式】

     棋盘游戏 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  9. 把js生成的内容放入网页原有的div上

    <script> ; ; //5列 ); ; var htmlstr="<table style='position:absolute;top:9%;left:10%; b ...

  10. 【转】带你正确的使用List的retainAll方法求交集

    一. retainAll 方法 public boolean retainAll(Collection<?> c) { //调用自己的私有方法 return batchRemove(c, ...