文档章节

nodejs __proto__跟prototype

A
 Ai5tbb
发布于 06/25 22:53
字数 965
阅读 12
收藏 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
博文 18
码字总数 3173
作品 0
程序员
Node.js 之使用util模块实现events的继承详解

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

造化玉碟
2014/05/09
0
0
js中的prototype和__proto__

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

LorinLuo
2016/01/30
146
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
__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

没有更多内容

加载失败,请刷新页面

加载更多

ReentrantLock_可重入

package cunrent;import java.util.Calendar;import java.util.concurrent.locks.ReentrantLock;public class TestReentrantLock { public static void main(String[] args......

noteman
37分钟前
2
0
CentOS7下安装mysql5.7

1、安装YUM Repo 由于CentOS 的yum源中没有mysql,需要到mysql的官网下载yum repo配置文件。 wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm 然后进行repo的安...

JungleKing
45分钟前
2
0
DevExpress v18.1新版亮点——DevExtreme篇(三)

用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容。本文将介绍了DevExtreme JavaScript Controls v18.1 的新功能,快来下载试用新版本!点击下载...

Miss_Hello_World
46分钟前
1
0
LoadRunner 安装

如果安装LoadRunner 11时弹窗提示"Micosoft Visual C++ 2005 SP1 可再发行组件包(X86):'命令行选项语法错误。键入命令 / ? 可获得帮助信息'"。或者弹窗提示"此计算机缺少 vc2005_sp1_wit...

ww1234
55分钟前
1
0
两个时间段相隔自然月Util

public class DateUtil { public static int getDay(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return calend......

木九天
58分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部