2

I am looking at this article regarding the node.js events module:

http://www.sitepoint.com/nodejs-events-and-eventemitter/

And in it there is this code:

Door.prototype.__proto__ = events.EventEmitter.prototype;

Which supposedly sets the prototype of the Door object to the prototype of the event.EventEmitter.

I believe I know what is the difference between prototype and proto but this code completely confuses me. So my questions is whether instead of using:

Door.prototype.__proto__ = events.EventEmitter.prototype;

The author of the article did not just use this line of code:

Door.prototype= events.EventEmitter.prototype;
4
  • If he did that, then all properties added to Door.prototype would also be added to events.EventEmitter.prototype because they'd be a reference to the same object. Commented Jul 17, 2015 at 11:44
  • ...I'd never set it up that way though. I'd just do Door.prototype = Object.create(events.EventEmitter.prototype); and then assign methods to Door.prototype as needed. Commented Jul 17, 2015 at 11:45
  • 1
    Door.prototype.__proto__ = events.EventEmitter.prototype is a bad way of Door.prototype = Object.create(events.EventEmitter.prototype). To compare with Door.prototype = events.EventEmitter.prototype, see Benefits of using Object.create for inheritance Commented Jul 17, 2015 at 12:03
  • There has been discussion lately about whether or not the __proto__ property should even be writable. It allows you to modify the prototype chain at runtime, which some argue could be a security flaw. Commented Jul 17, 2015 at 12:37

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

And in your own code, be sure to use the Object.create() approach - it's the correct way, and doesn't result in unpleasant surprises or loss of performance.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.