{"action":"created","issue":{"url":"https://api.github.com/repos/joyent/node/issues/8210","labels_url":"https://api.github.com/repos/joyent/node/issues/8210/labels{/name}","comments_url":"https://api.github.com/repos/joyent/node/issues/8210/comments","events_url":"https://api.github.com/repos/joyent/node/issues/8210/events","html_url":"https://github.com/joyent/node/issues/8210","id":40714594,"number":8210,"title":"events: Introducing a third \"context\" argument to eventemitter.on","user":{"login":"3rd-Eden","id":28071,"avatar_url":"https://avatars.githubusercontent.com/u/28071?v=3","gravatar_id":"","url":"https://api.github.com/users/3rd-Eden","html_url":"https://github.com/3rd-Eden","followers_url":"https://api.github.com/users/3rd-Eden/followers","following_url":"https://api.github.com/users/3rd-Eden/following{/other_user}","gists_url":"https://api.github.com/users/3rd-Eden/gists{/gist_id}","starred_url":"https://api.github.com/users/3rd-Eden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/3rd-Eden/subscriptions","organizations_url":"https://api.github.com/users/3rd-Eden/orgs","repos_url":"https://api.github.com/users/3rd-Eden/repos","events_url":"https://api.github.com/users/3rd-Eden/events{/privacy}","received_events_url":"https://api.github.com/users/3rd-Eden/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/joyent/node/labels/events","name":"events","color":"e10c02"},{"url":"https://api.github.com/repos/joyent/node/labels/feature-request","name":"feature-request","color":"0b02e1"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2014-08-20T16:05:52Z","updated_at":"2015-06-24T17:37:19Z","closed_at":null,"body":"#### Problem\r\n\r\nThe `EventEmitter` calls the supplied functions with it's own context. If you want to pass in a function to an event emitter from your own class you either need to wrap or bind your function which causes loss of performance. See the following example:\r\n\r\n```js\r\nfunction Foo() {}\r\nFoo.prototype.handle = function handle(req, res) {\r\n  this.headers(res);\r\n  res.end('bar')\r\n};\r\nFoo.prototype.headers = function headers(res) {\r\n  res.setHeader('foo', 'bar');\r\n}\r\n\r\nvar http = require('http').createServer(),\r\n   foo = new Foo();\r\n\r\nhttp.on('request', foo.handle.bind(foo));\r\n// or\r\nhttp.on('request', function (req, res) { foo.handle(req, res) })\r\n```\r\n\r\nThis isn't just a problem with http modules but everything in node that inherits from the eventemitter.\r\n\r\n#### Solution\r\n\r\nThe solution is to add an extra `context` argument to the `EventEmitter.on` method which will \r\nensure that the eventlistener is called with the supplied context instead of the context of the eventemitter. It would be fully backwards compatible as the third argument is not used:\r\n\r\n```js\r\nhttp.on('request', foo.handle, foo);\r\n```\r\n\r\nAn example implementation of this could be found in the `eventemitter3` module https://github.com/3rd-Eden/EventEmitter3/blob/master/index.js#L32-L102\r\n\r\nAs for the performance gain:\r\n\r\n```\r\nNode's EventEmitter using bind\r\nCount (66192), Cycles (6), Elapsed (5.485), Hz (1272665.3236835978)\r\n\r\nEventEmitter3 with using the 3rd argument for context\r\nCount (363111), Cycles (4), Elapsed (5.412), Hz (6888645.436669402)\r\n\r\nEventEmitter3 using bind\r\nCount (70391), Cycles (6), Elapsed (5.4), Hz (1339867.5996333812)\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/joyent/node/issues/comments/114950386","html_url":"https://github.com/joyent/node/issues/8210#issuecomment-114950386","issue_url":"https://api.github.com/repos/joyent/node/issues/8210","id":114950386,"user":{"login":"jasnell","id":439929,"avatar_url":"https://avatars.githubusercontent.com/u/439929?v=3","gravatar_id":"","url":"https://api.github.com/users/jasnell","html_url":"https://github.com/jasnell","followers_url":"https://api.github.com/users/jasnell/followers","following_url":"https://api.github.com/users/jasnell/following{/other_user}","gists_url":"https://api.github.com/users/jasnell/gists{/gist_id}","starred_url":"https://api.github.com/users/jasnell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasnell/subscriptions","organizations_url":"https://api.github.com/users/jasnell/orgs","repos_url":"https://api.github.com/users/jasnell/repos","events_url":"https://api.github.com/users/jasnell/events{/privacy}","received_events_url":"https://api.github.com/users/jasnell/received_events","type":"User","site_admin":false},"created_at":"2015-06-24T17:37:18Z","updated_at":"2015-06-24T17:37:18Z","body":"@trevnorris @3rd-Eden ... any updates on this one?"}}