Setting Object.prototype.__proto__ instead of just Object.prototype?

落爺英雄遲暮 提交于 2019-11-29 12:21:59

This code

Door.prototype.__proto__ = events.EventEmitter.prototype

makes Door.prototype inherit from events.EventEmitter.prototype.

So the prototype chain will be like

doorInstance -> Door.prototype -> events.EventEmitter.prototype

This approach is similar to

Door.prototype = Object.create(events.EventEmitter.prototype)

The difference is that modifying the [[Prototype]] does not create a new object, but it has a great negative impact on performance.

Instead, this code

Door.prototype = events.EventEmitter.prototype

makes Door instances inherit directly from events.EventEmitter.prototype.

That is, you won't be able to add specific methods in Door.prototype without polluting events.EventEmitter.prototype.

I did some more research on this and although there are various diagrams on the matter I think this graphic explains it best:

http://www.mollypages.org/misc/js.mp

To summarize:

  1. Door.prototype is only available on the Door type not on the instances of Door.

  2. doorInstance.__proto_ gets set to Door.prototype (points to Door.prototype) when the doorInstance is created view new Door().

  3. Interestingly Door.prototype has a __proto_ property of its own (Door.prototype.__proto_) which points to Object.prototype.

  4. When properties get looked up as part of the Javascript prototypal inheritance the __proto_ property is used on each object in the prototypal chain. We can forget about the prototype property as it is not present on instances. For example doorInstace -> doorInstance.__proto_ -> doorInstance.__proto_.__proto_. So ultimately the last __proto_ to be looked up will be the one pointing to the Object.prototype.

So going back to the question, setting the Door.prototype.__proto_ like this:

Door.prototype.__proto_ = events.EventEmitter.prototype

Will in reality change the Door.prototype.__proto_ to point to the events.EventEmitter.prototype instead of the Object.prototype. In this way properties on the doorInstance will be looked up in the following order: doorInstance -> doorInstance.__proto_ -> doorIntacne.__proto_.__proto (events.EventEmitter.prototype)

In this way doorInstance is essentially inheriting from events.EventEmitter.prototype.

This code:

Door.prototype = events.EventEmitter.prototype;

Will have the same effect because doorInstance.__proto_ points to Door.prototype and setting Door.prototype to events.EventEmitter.prototype will make doorInstance.__proto_ point to events.EventEmitter.prototype. In this way properties on the doorInstance will be looked up in the following order: doorInstance -> doorInstance.__proto_(events.EventEmitter.prototype).

However as already answered by Oriol, because Door.prototype and events.EventEmitter.prototype now point to the same object, changes in either prototype will affect the other prototype, which can result in unexpected behavior.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!