10 ms·
I don't like the explanation as a set of piecewise cases. this just refers to the current object context. this refers to the window at the top level because you
by rjeli 9y ago
I don't like the explanation as a set of piecewise cases. this just refers to the current object context. this refers to the window at the top level because you're operating within `window`. There aren't "simple functions" and "object constructor functions", just functions, and the `new` keyword executes the function within the context of a new object. Event listeners are not a special case, it's just that the callback is executed from the context of the event -- which makes the difference between `function (e) { this }` and `e => this` much easier to understand.
- abritinthebay 9y agoAgreed. It’s extremely poorly explained and quite misleading
- fenomas 9y agoI agree. The key to grokking this is the difference between a function's execution context and its lexical scope. If you don't explain that I don't think you've explained anything, and if you do then there's no need to think about separate cases like the article suggests.
- Joeri 9y agoIf you think of javascript code like an english sentence, then the function is the verb, the context (this) is the subject and the scope (arguments, closed over variables) are the nouns.
- rippeltippel 9y agos/nouns/objects/g (then the analogy works for me)
- sheldor 9y ago> I don't like the explanation as a set of piecewise cases We don't like it and it's redundant. One should learn the principles and return to this article to read it as a quiz and find out whether he got it or not. Books like the excellent Javascript Allonge (free to read on leanpub) do a great job on explaining the context. If you need more hardcore stuff, "You don't know JS" will fit you better. (Disclaimer: I'm not affiliated with any of the recommended books or their authors or leanpub or whatever.They just helped me a lot; and still do from time to time)
- carussell 9y agoThe unfortunate thing about the lengths people go to in order to try to "fix" `this` in event handlers is that it wouldn't be a problem if people just implemented the event listener interface correctly. PSA Don't do this: proto.foo = function() { /* ... */ var self = this; element.addEventListener("click", (function(event) { self.iHaveAnUnhealthyObsessionWithLambdas(event.target); })); } proto.iHaveAnUnhealthyObsessionWithLamdas = function(clicked) { /* do something with clicked element `clicked` */ } Do this instead: proto.foo = function() { /* ... */ element.addEventListener("click", this); } proto.handleEvent = function(event) { /* do something with clicked element `event.target` */ }
- thousande 9y agoToday I learned In general, a good practice is to avoid anonymous functions for the listener else it is not possible to remove the event later.
- wiredearp 9y agoI guess the function could still be anonymous, but you will at least need to keep it assigned to some variable or property name. If you make use of the `handleEvent` pattern that @carussell suggested, you can however avoid having to keep track of all these callback functions since the listener can always be removed by passing `this` a second time: ['click', 'focus', 'blur'].forEach(type => elm.removeEventListener(type, this));
- icebraining 9y agoBut then if you're listening to multiple events, won't you have to try to disambiguate after the fact in handleEvent()?
- wiredearp 9y agoThat's the fun part, because here you can code your event handling to read something more like a state machine. Here's a quick example in bogus code, adding and removing event listeners as we go along (and without keeping reference to all the callback functions): class ElementDragger { constructor(elm) { elm.addEventListener('mousedown', this); } handleEvent(e) { const elm = e.target; switch(e.type) { case 'mousedown': elm.removeEventListener('mousedown', this). elm.addEventListener('mousemove', this); elm.addEventListener('mouseup', this); break; case 'mousemove': elm.style.left = e.clientX + 'px'; break; case 'mouseup': elm.removeEventListener('mousedown', this); elm.removeEventListener('mouseup', this); elm.addEventListener('mousedown', this); break; } } }
- v413 9y agoAs an event listener "function(e) {this}" is not the same as "(e) => this". With the regular function "this" points to the element on which the event listener was attached to while with the arrow function "this" points to the context (i.e. "this") of its lexical environment.
- christophilus 9y agoThat's what the OP was saying.
- pier25 9y ago> this just refers to the current object context Exactly. "If you can't explain it simply, you don't understand it well enough." Albert Einstein
- zappo2938 9y agoThis refers the to the object left of the .