文档章节

nodejs __proto__跟prototype

A
 Ai5tbb
发布于 06/25 22:53
字数 965
阅读 17
收藏 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 Interview ---- 类型判断

Node.js Interview ---- 类型判断 基本数据类型: Number,String,Boolean,Undefined,Null,Symbol 复杂数据类型: OBject console.log("aa" == true) // false const a = {i: 1,toString: funct......

Even
10/05
0
0
如何理解JavaScript的原型和原型链?

之前有朋友在公众号给我留言,问问怎么去理解原型和原型链的问题。这个问题,在面试中,很多同学经常都会遇到。 回复多了,觉得大家对这块知识点理解还是不够深。于是决定今天来给大家讲讲,...

WEB开发阿靖
12/07
0
0
__proto__ && prototype

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

秋风醉了
2014/07/21
0
0
JavaScript 原型总结四 隐式原型

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

张泽立
01/28
0
0
Javascript的原型、原型链、原型链继承

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

xiedrsz
2017/07/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mybatis学习(1)

JDBC连接方式: 1.底层没有使用连接池,操作数据库需要频繁的创建和关闭连接,消耗资源。 2.写原生的JDBC代码在JAVA中,一旦需要修改SQL的话(比如表增加字段),JAVA需要整体重新编译,不利...

杨健-YJ
19分钟前
0
0
怎么组织文档

可以从以下几个方面考虑组织文档: ☐ 各种分支的界面截图和对应的类及文件 ☐ 框架或类图 ☐ 流程图 ☐ 时序图 ☐ 注意事项

-___-
31分钟前
1
0
分布式之数据库和缓存双写一致性方案解析

引言 为什么写这篇文章? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。 但是在更新缓存方面,对于更...

别打我会飞
33分钟前
5
0
我的oracle11G,12c OCM之路

ocm认证感悟 ---------------------- 距离拿到ocm证书已经过了1年的时间,当初拿到证书的心情到现在还记得。其实在每个DBA心里都有一个成为强者的梦想,需要被认可,我也一样。我干过开发,做...

hnairdb
34分钟前
1
1
手动部署kubernetes集群(1.13.1最新版)

一、机器规划 使用五台机子部署k8s集群,规划如下: master节点3台(同时也是etcd节点) node节点2台 ip分配如下: ip:192.168.10.101,主机名:k8s-etcd01 ip:192.168.10.102,主机名:k8s...

人在艹木中
39分钟前
28
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部