3 ms·
This article does a good job of explaining a concept I had trouble with when first using javascript. Now, I usually use the approach recommended in the article
by Bluem00 17y ago
This article does a good job of explaining a concept I had trouble with when first using javascript. Now, I usually use the approach recommended in the article of setting a private variable (e.g. self, or my) to the current value of 'this' in a javascript class.
However, I think the article is slightly incorrect on one minor point. It states, "this wants to be window whenever possible, which is not always what you want." I believe the correct description is: the 'this' variable in a function called in response to an event on dom object is set to that dom object. For the example given in the article, this is set to the window object because setTimeout causes an event on window to fire, not because there's any inherent preference for the window object.
- aboodman 17y agoThere is indeed a preference for window (really the global) object. Try these: <script> alert(this == window); function foo() { alert(this == window); } foo(); </script> |this| is basically a magical variable that by default is set to the global object, but can also be set by the caller of a function one of two ways: a) by setting a reference to the function on an object, and calling it with object or bracket notation: var someObj = {}; someObj.f = theFunction; someObj.f(); // now |this| inside theFunction will // point to someObj someObj["f"](); // same thing b) by using apply: theFunction.apply(someObj); You are right that in the case of event handlers, it is common in the DOM for event handlers to get their |this| set to the DOM node that fired the event. Since the default value of |this| is the global object, it isn't possible in the case of setTimeout for us to tell whether the caller (the host) explicitly set it, or if the function is being called without any value set for |this|. Basically, |this| is an extra parameter to any function. It is controlled by the caller, and as such, should either be documented as part of the signature of the function, or else should not be relied on by the implementation of the function. The common misunderstanding with people new to JS is that they expect |this| to be controlled by the callee, like it is in lots of other popular languages, and are surprised when calling convention can change its value.
- aboodman 17y agoBTW, imo, the behavior of |this| is a really unfortunate design flaw of JS. The amount of time that must have been spent learning and teaching this edge case over and over to every person new to the language is ... well, it's big.
- Bluem00 17y agoDo you know why it was designed this way? Was 'new' added to javascript after the behavior of 'this' was already well defined and the creators did not feel comfortable changing it?
- jmtulloss 17y agoactually, no. As I understand it, the language was supposed to be some sort of weird conglomeration between traditional object oriented languages and dynamic, lisp-ish languages. The problem was that the creators had about 30 seconds to get this done and they could make things look more "normal" by not explicitly supporting every feature they envisioned. "new", I believe, is actually an ancient relic of the prototypal class system. That's another topic entirely, but it's incredibly cool. Check out Douglas Crockford's articles on inheritance if you want closure on the issue. He has written way more than I have on the topic.
- praptak 17y ago"new", I believe, is actually an ancient relic of the prototypal class system. I believe it is quite the opposite. It was a failed attempt to make the prototype-based object system look like class-based one. I vaguely remember reading this opinion in Crockford's "Javascript:The Good Parts" book.
- jmtulloss 17y agoAgreed. That's actually what I was trying to say. It's an ancient relic of JavaScript's implementation of the class system.
- jmtulloss 17y agoThat was a bit inexact. It's kind of a hard point to generalize, I gave it another go.
- Bluem00 17y agoAboodman seems to have a better handle on it than I do. I think what I said about the dom object is correct, but he point out that window is the default value of this for other function calls.