nodejs __proto__跟prototype

本文详细介绍了Node.js中如何通过原型链实现继承,包括对象的属性和方法的定义,构造函数的使用,以及如何利用原型对象减少内存消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

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()方法了,从而能减少内存消耗的实现了面向对象编程的继承了。

转载于:https://my.oschina.net/u/3714085/blog/1835377

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值