文档章节

nodejs __proto__跟prototype

A
 Ai5tbb
发布于 06/25 22:53
字数 965
阅读 6
收藏 0
点赞 0
评论 0

前言

nodejs中完全没有class的这个概念,这点跟PHP,JAVA等面向对象的语言很不一样,没有class跟object的区分,那么nodejs是怎么样实现继承的呢?

对象

对象是由属性跟方法组成的一个东西,就像下面这样:

var animal = {
	name: "animal",
	eat: function () {
	console.log('%s is eating', this.name);
	}
};

animal.eat(); //animal is eating.

由于nodejs中object完全不和class关联,我们可以自由的给对象添加属性和方法:

animal.color = 'black';
animal.say = function () {
	console.log('I am color %s', this.color);
}
console.log(animal.color); //black
animal.say(); //I am color black

怎么像面向对象里的类那样实现继承?

继承是面向对象中的重要概念,实际上是把两个对象建立关联;nodejs中每个对象都有一个__proto__属性,要建立两个对象之间的关联就要用到这个属性了:一个对象可以使用__proto__关联另外一个对象(这个对象就是原型):

var cat = {
	name: 'cat',
	__proto__: animal
};

var dog = {
	name: 'dog',
	__proto__: animal
};

cat.eat(); //cat is eating
dog.eat(); //dog is eating

对象cat的原型是animal,对象dog的原型也是animal,并且它们两个都没有定义eat()方法,那是怎么调用eat()方法的呢?

答案是nodejs的机制,当cat对象调用eat方法时,cat对象会现在自己的方法中寻找eat方法,如果找不到,就会去原型的方法中寻找,如果原型中找不到,就会去原型的原型中去寻找...最后就会去Object那里去找,如果还找不到,那就是这个方法未定义了。

这样,animal、cat、dog这三个对象通过__proto__建立起了一个原型链。在这里,dog跟cat对象的name属性覆盖了animal的name属性,还有this,在cat跟dog对象在调用eat方法时,分别指向了cat跟dog对象。

让nodejs可以new出对象来,更贴近面向对象编程

为了让nodejs内的对象可以像面向对象编程那样可以new出一个对象实例,nodejs提供了一个叫做构造函数的东西:

function Student(name) {
	this.name = name;
	this.sayHello = function () {
		console.log('Hello, my name is %s', this.name);
	}
}

var tom = new Student('Tom');
var mike = new Student('Mike');

tom.sayHello(); //Hello, my name is Tom
mike.sayHello(); //Hello, my name is Mike

为了让代码更规范,构造函数的名称首字母要大写。在这里有没有发现一个问题,传统的面向对象编程中,方法都是定义在类中的,我们这里的代码是定义在对象上的,这样就意味着每一个由构造函数new出来的对象都附带一个sayHello的方法,这样太浪费空间了。于是,nodejs就创造出了一种更高效的方法,将sayHello方法放到别的地方去。
还记得刚才说的原型链吗?当一个对象调用方法时,会顺着原型链向上找,所以我们可以创建一个
原型对象
,将要调用的方法放到这个原型对象中,让tom、mike这些从Student创建的对象指向这个原型就行了:

function Student(name) {
	this.name = name;
}

Student.prototype = {
	sayHello: function () {
		console.log('Hello, my name is %s', this.name);
	}
}

var tom = new Student('Tom');
var mike = new Student('Mike');

tom.sayHello(); //Hello, my name is Tom
mike.sayHello(); //Hello, my name is Mike

每当new Student()时,确实会创建一个新的对象,并且把这个对象的原型__proto__指向Student.prototype这个对象,这样一来就能找到sayHello()方法了,从而能减少内存消耗的实现了面向对象编程的继承了。

© 著作权归作者所有

共有 人打赏支持
A
粉丝 0
博文 17
码字总数 2805
作品 0
程序员
Node.js 之使用util模块实现events的继承详解

这是一个很重要的继承方式。使用util包模块的inherits方法来实现简单继承 1. inherits的继承机制源码 exports.inherits = function(ctor,superCtor){ ctor.super_=superCtor; ctor.prototype...

造化玉碟
2014/05/09
0
0
Node v0.12.4 (Stable) 发布,JavaScript 脚本

Node v0.12.4 (Stable) 发布,此版本更新信息如下: npm: upgrade to 2.10.1 V8: revert v8 Array.prototype.values() removal (cjihrig) win: bring back xp/2k3 support (Bert Belder) 下载......

oschina
2015/05/24
2.6K
4
远程通信协议:从 CORBA 到 gRPC

自从产业界发明机器联网的那一天就已经开始探索最优的远程通信机制。操作系统如 UNIX、Windows 和 Linux 等都有实现远程通信的内部协议,挑战在于如何向开发人员开放一个通信框架。 一、远程...

RiboseYim
2017/10/31
0
0
Nodejs系列文章之:javascript代码进阶篇

作者: RobanLee (Code maker, PHP,JS,NODEJS,PYTHON, blog:http://my.oschina.net/robanlee) javascript & nodejs 一些进阶知识: 1. 如何快速进行string => int 的转换? 大家一般首先想到的就......

_dedecms
2014/05/07
0
2
js中的prototype和__proto__

prototype是函数的属性,每个函数都拥有一个prototype属性;proto是一个对象拥有的内置属性,是new一个实例时动态添加的属性,也是js内部寻找原型链的属性。 prototype属性拥有一个construct...

LorinLuo
2016/01/30
146
0
__proto__ && prototype

proto && prototype 一个对象的proto 属性和自己的内部属性[[Prototype]]指向一个相同的值 (通常称这个值为原型),原型的值可以是一个对象值也可以是null(比如说Object.prototype.__proto__的...

秋风醉了
2014/07/21
0
0
Javascript的原型、原型链、原型链继承

原型 在javascript中,原型分有两种:显示原型(prototype)和隐式原型(proto)。 proto(隐式原型) JavaScript中任意对象都有一个内置属性,在ES5之前没有标准的方法访问这个内置属性,但...

xiedrsz
2017/07/03
0
0
JavaScript 原型总结四 隐式原型

1.隐式原型 上节已经提到,每个函数function都有一个prototype,即原型。这里再加一句话——每个对象都有一个proto,可成为隐式原型。 obj这个对象本质上是被Object函数创建的,因此obj.pro...

张泽立
01/28
0
0
Google Protocol Buffer 的各语言实现版本

Google Protocol Buffer 专门用来串行化和反串行化对象,但官方仅实现了C++、Python、Java三种语言。其他语言版本也相继由不同的作者来实现。虽然有一定缺陷,也足以在大部分的项目中使用了。...

啊和
2013/07/23
0
0
ES5和ES6中的继承

ES5 ES5中的继承,看图: ES5中这种最简单的继承,实质上就是将子类的原型设置为父类的实例。 ES6 ES6中的继承,看图: 所以 ES6和ES5的继承是一模一样的,只是多了class 和extends ,ES6的子...

WolfX
2016/06/03
52
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

程序的调试信息

调试二进制程序时,经常要借助GDB工具,跟踪程序的执行流程,获取程序执行时变量的值,以发现问题所在。GDB能得到这些信息,是因为编译程序时,编译器保存了相应的信息。Linux下的可执行程序...

qlee
30分钟前
0
0
应用级缓存

缓存命中率 从缓存中读取数据的次数与总读取次数的比例,命中率越高越好 java缓存类型 堆缓存 guavaCache Ehcache3.x 没有序列化和反序列化 堆外缓存ehcache3.x 磁盘缓存 存储在磁盘上 分布式...

writeademo
今天
0
0
python爬虫日志(3)find(),find_all()函数

1.一般来说,为了找到BeautifulSoup对象内任何第一个标签入口,使用find()方法。 以上代码是一个生态金字塔的简单展示,为了找到第一生产者,第一消费者或第二消费者,可以使用Beautiful Sou...

茫羽行
今天
0
0
java:thread:顺序执行多条线程

实现方案: 1.调用线程的join方法:阻塞主线程 2.线程池 package com.java.thread.test;public class MyThread01 implements Runnable {@Overridepublic void run() {Syste...

人觉非常君
今天
0
0
ElasticSearch 重写IK分词器源码设置mysql热词更新词库

常用热词词库的配置方式 1.采用IK 内置词库 优点:部署方便,不用额外指定其他词库位置 缺点:分词单一化,不能指定想分词的词条 2.IK 外置静态词库 优点:部署相对方便,可以通过编辑指定文...

键走偏锋
今天
18
0
Git 2.18版本发布:支持Git协议v2,提升性能

Git 2.18版本发布:支持Git协议v2,提升性能Git 2.18版本发布:支持Git协议v2,提升性能 新版本协议的主要驱动力是使 Git 服务端能够对各种 ref(分支与 tag)进行过滤操作。 这就意味着,G...

linux-tao
今天
0
0
python浏览器自动化测试库【2018/7/22-更新】

64位py2.7版本 更新 document_GetResources 枚举页面资源 document_GetresourceText 获取指定url的内容 包括页面图片 下载地址下载地址 密码:upr47x...

开飞色
今天
41
0
关于DCL双重锁失效及解决方案

关于DCL双重锁失效及解决方案 Double Check Lock (DCL)实现单例 DCL 方式实现单例的优点是既能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化后调用getInstance方法不进行...

DannyCoder
今天
0
0
PowerDesigner 16.5 安装配置

PowerDesigner16.5破解版是一款业内领先且开发人员常用的数据库建模工具,PowerDesigner可以从物理和概念两个层面设计数据库,方便用户制作处清晰直观的数据流程图和结构模型,欢迎有需要的朋...

Gibbons
今天
0
0
mac Homebrew 指令积累

1通用命令 brew install [包名] //安装包 brew list //列举安装的包 brew info [包名] // 显示安装包的详细信息 mysql 相关 #启动mysql 服务 brew service start mysql my...

Kenny100120
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部