Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype bleeding in events.js #2044

Closed

Conversation

martinheidegger
Copy link

Inheriting from EventEmitter using .prototype-old-school-notation like this:

var MyClass = function() {};
MyClass.prototype = new EventEmitter();

will result in the listeners added to one instance being executed by listeners of another instance.

var ok = new MyClass();
var broken = new MyClass();
broken.on('x', function () { console.log('b'); });
ok.on('x', function () { console.log('a'); });
ok.emit('x'); // b a

This can be quite easily resolved by changing the inheritance to:

util.inherits(MyClass, EventEmitter);

or

MyClass.prototype = Object.create(EventEmitter.prototype);

but it still is a problem because even developers like substack seem to not be aware of this: https://github.com/substack/node-charm/blob/c6646deed2dcee7f512bbbfac6d2ab58fb528a68/index.js#L67

This PR - at the time of writing this - still just contains just the test. I am not sure how to fix this. Any help welcome.

Note: This fixes a problem that exists in older node versions as well, however: I found this bug/problem while investigating a different bug that started to appear in io.js after version 1.3.0 either due to 7061669dba or 630f636334 However my other bug was too hard to properly reproduce. Fixing this will fix the other bug as well.

@brendanashworth brendanashworth added events Issues and PRs related to the events subsystem / EventEmitter. test Issues and PRs related to the tests. labels Jun 23, 2015
@vkurchatkin
Copy link
Contributor

This is a regression (I think)

@bnoordhuis
Copy link
Member

I think so too. nodejs/node-v0.x-archive#7157 was fixed over a year ago.

TestClass.prototype = new EventEmitter;

function listener_n1() {
// This one is okay to be called!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function must be called, right? Why not assign some value to a variable here and check if the value is set in process.exit?

@martinheidegger
Copy link
Author

@thefourtheye Thank you for pointing the various things out. I pushed a style correction.

@thefourtheye
Copy link
Contributor

I think we really have nothing to do here. Just clarifying how to properly inherit from EventEmitter in the docs should be enough. #2168

@brendanashworth
Copy link
Contributor

The doc change was landed in d168d01. @thefourtheye is this still up for landing or should it be closed?

@martinheidegger
Copy link
Author

https://github.com/search?utf8=%E2%9C%93&q=%22.prototype+%3D+new+EventEmitter%28%29%22&type=Code&ref=searchresults 4000 entries + in github that use that problematic, non-standard use of EventEmitter (word by word). And they are usually submissions of people that are confident enough to submit something to github. If it is only treated as a "documentation fixes this issue" (which I think it doesnt) then it should specifically mention that incompatibility.

Note: Old-school JavaScript inheritance like MyEventEmitter.prototype = new EventEmitter() does not work.

Also I think that it should be more prominent in the docs that this way of inheritance is actively regarded as harmful.

@thefourtheye
Copy link
Contributor

@brendanashworth sorry. I couldn't respond earlier. But we already have this regression here https://github.com/nodejs/node/blob/master/test/parallel/test-event-emitter-subclass.js#L38-L49. So we can close this.

@martinheidegger You may want to propose a documentation change in a separate PR.

@brendanashworth
Copy link
Contributor

It is unfortunate that so many people use this inheritance, but it doesn't make sense in the least. I agree a documentation fix is in order. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
events Issues and PRs related to the events subsystem / EventEmitter. test Issues and PRs related to the tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants