TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

“This” in JavaScript

256 pointsby alphabetamover 10 years ago

27 comments

couchandover 10 years ago
The author critically misunderstands the way that `this` gets set, and in doing so has developed a significantly overcomplicated mental model. This is exemplified in the statement:<p><i>You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new. ... Note, there was no use of new , no Object.create and no function called to create obj.</i><p>This is exactly the same behavior that you see on an object method reference, and drawing any distinction at all makes understanding the behavior of <i>this</i> harder than it needs to be.<p>In nearly every case (with the exception of <i>bind</i>, <i>call</i> and <i>apply</i>) the <i>this</i> variable is set at the CALL SITE of the function, NOT THE DEFINITION. Note that in the three other cases, you still aren&#x27;t setting <i>this</i> at the definition.<p>The reason you get <i>this</i> behaving as the author describes on objects created with <i>new</i> is only (as the author nearly, but not quite, realizes) because you called the function in the form:<p><pre><code> thing.method() </code></pre> Specifically, it is the object reference that sets the <i>this</i> context within the method call.<p>You can be sure that the object literal case is just the same. You don&#x27;t need to call <i>new</i> to get an object reference that has a prototype chain: namely, an object literal is instantiated with the prototype <i>Object</i>. You can verify this is true with a simple:<p><pre><code> thing = {} thing.hasOwnProperty === Object.hasOwnProperty </code></pre> ...and so forth.
评论 #8715373 未加载
评论 #8714977 未加载
评论 #8716227 未加载
评论 #8714953 未加载
TazeTSchnitzelover 10 years ago
This post is way, way too long. Rather than explaining the simple principles that lead to the behaviour JS&#x27;s this has, the post just lists example after example.<p>JS &#x27;this&#x27; is a variable defined within a function. If that function is called as if it were a method, e.g. obj.somefunc(), &#x27;this&#x27; is that object, obj. Otherwise, &#x27;this&#x27; is the global object (quirks mode) or undefined (strict mode). If a function is called with the new keyword, &#x27;this&#x27; is set to a new object whose prototype is set to the property named &#x27;prototype&#x27; on the function.<p>The prototype of an object is a fallback: if you try to read a property on an object and it lacks such a property, it&#x27;ll grab it from its prototype (or its prototype&#x27;s prototype etc.) if it has it. If you write to or create a property on an object, it always goes on the object and won&#x27;t touch the prototype.<p>The weird behaviour for DOM events isn&#x27;t weird. It just calls the onclick method as a method.
评论 #8714954 未加载
ender7over 10 years ago
This is a pretty long article. The concepts you need to know aren&#x27;t so long:<p>There are three ways to invoke a function. The meaning of `this` depends on which method was used:<p>- If a function is invoked in the form `foo.func()`, then the value of `this` is `foo`.<p>- If a function is invoked in the form `func()` (sometimes called &quot;bare&quot;), then the value of `this` is the &quot;root object&quot;. In browsers the root object is `window`, in Node this it&#x27;s the `global` object [0]. It&#x27;s easier to make a bare invocation than you think:<p><pre><code> var bareFunc = foo.func; bareFunc(); </code></pre> - If a function is invoked via the `call()` or `apply()` function, then the value of `this` is whatever the invocation specifies. For example, in `func.call(foo)` the value of `this` will be `foo`.<p>If you ever pass a function to something else as a callback, you have no guarantee what the value of `this` will be when it is called. For example, if you register a callback for a click event, the value of `this` is whatever the caller wants it to be (in this case, it&#x27;ll be the DOM element that&#x27;s emitting the event):<p><pre><code> function MyFoo(elem) { elem.addEventListener(&#x27;click&#x27;, this.onClick); } MyFoo.prototype.onClick = function(e) { &#x2F;&#x2F; `this` is whatever the caller wanted it to be } </code></pre> You can force `this` to be a specific value by using the `bind()` function:<p><pre><code> function MyFoo(elem) { elem.addEventListener(&#x27;click&#x27;, this.onClick.bind(this)); } MyFoo.prototype.onClick = function(e) { &#x2F;&#x2F; `this` has been bound to what you think it should be. } </code></pre> [0] However, if you&#x27;re in strict mode, then in either case `this` will be `undefined`.
评论 #8715210 未加载
_mtrover 10 years ago
Not mentioned are ES6&#x27;s arrow functions that capture the `this` value of the enclosing context.<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions" rel="nofollow">https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;JavaScript&#x2F;Refe...</a>
评论 #8714679 未加载
评论 #8714993 未加载
nmjohnover 10 years ago
&gt; JavaScript is not such a language. ... There are many “gotchas”<p>I don&#x27;t disagree, like all languages javascript has its quirks (more than some, fewer than others, all depending on a given developers perspective) but I fail to see this conclusion being supported by the article itself.<p>Basically every quirk in it was a result of &#x27;use strict&#x27; preventing a developer from leaking variables (and thus `this`) in ways they shouldn&#x27;t be doing - which results in slightly different behavior when strict mode is enabled. The only real quirk I see here is the fact that strict mode isn&#x27;t enabled by default (or better yet not even an option to turn off) but that is because it would kill backwards compatibility.<p>&#x27;this&#x27; in actuality is pretty straightforward - unless you make it complex. (Which javascript does make it very easy for you to do, which means bad code will be written doing just that. But bad code is bad code regardless.)<p>When you define a new function, the contents will have a different scope and &#x27;this&#x27; will be different. If you want to access the parent this in a nested function, you either call the function with the &#x27;this&#x27; bound, or you do `var self=this;` in the parent scope, and use &#x27;self&#x27; in lieu of &#x27;this&#x27;.<p>That is pretty much it - I can see how it is a bit tricky at first, but after spending a bit of time working on javascript it really isn&#x27;t something you have to consciously think about too often.<p>I don&#x27;t think it is inherently bad, just different. Back when I was writing Java I would have told you I like their approach better, but now after writing almost exclusively javascript for the last year or so, I would say I like the javascript &#x27;this&#x27; better. At the end of the day they are just different and a developer needs to learn the intricacies of whichever language they are developing in. (Since criticizing javascript is trendy on hn these days, if you want something to be critical of javascript about that can objectively be explained, go with the lack of static typing or the related quirky type coercion in equality checking resulting in (2 == [2]) =&gt; true.)
评论 #8715604 未加载
drcodeover 10 years ago
The title of this post alone fills me with anxiety and loathing. The only title I could think of that would be worse for a post is &quot;Taxes you&#x27;ve been paying for years but didn&#x27;t have to&quot;.<p>(great essay BTW on a hated subject :-)
评论 #8715039 未加载
_RPMover 10 years ago
I skimmed the article. I began to get anxiety once I realized how long it was. JavaScript is a very simple language. `this` in JavaScript is easy to understand. Long posts like this give me anxiety.
评论 #8714816 未加载
评论 #8715198 未加载
nchelluriover 10 years ago
There&#x27;s a nice link at the end of the post to another article that is simpler. I personally liked reading both. Here&#x27;s the link: <a href="http://tomhicks.github.io/code/2014/08/11/some-of-this.html" rel="nofollow">http:&#x2F;&#x2F;tomhicks.github.io&#x2F;code&#x2F;2014&#x2F;08&#x2F;11&#x2F;some-of-this.html</a>
iglover 10 years ago
In short: this is a reference to a functions context. If no context is present it points to the global context or if encapsulated to undefined.<p>context.func() &#x2F;&#x2F;this == context<p>func() &#x2F;&#x2F; this == global
kristiandupontover 10 years ago
I hated JS in the beginning, trying to make write it more like I write C# or C++ (I have experience with other languages, but the syntax lead me to believe that this style would be best suited). I wrote &quot;self = this&quot; a lot.<p>Now, I have adopted a much more functional style and I find JS increasingly pleasant to work with every day. To the point where many of the new ES6 features are a bit worrying because it looks like they want to take it in the direction of what I wanted it to be when I started. At this point, using &quot;this&quot; or &quot;prototype&quot; is almost a smell -- they&#x27;re useful at times but whenever I use them something in the back of my mind tells me that I could probably be doing something more elegant.
评论 #8715618 未加载
eric_hover 10 years ago
I&#x27;ve used this gist: <a href="https://gist.github.com/erichummel/2595398" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;erichummel&#x2F;2595398</a> a few times in interviews to see just how much of a javascript whiz candidates were.<p>The basic gist of the interview question is &quot;what is output to the console when this code is run?&quot;<p>It&#x27;s obviously intentionally obfuscated, so even if the candidate got it wrong (most did), subsequently talking through the solution told me a lot about how good a candidate was at static analysis and talking through a problem.
评论 #8718457 未加载
jMylesover 10 years ago
There&#x27;s something to be said about the distinction between &quot;this&quot; and &quot;self&quot; as names for the self-referential instance object. While &quot;self&quot; emphasizes mutability and introspection, &quot;this&quot; evokes a more material, evidentiary abstraction.<p>When I transitioned from PHP to Python, the change in nomenclature (albeit only a social norm in Python) was a big part of what helped me think bigger about this concept.<p>To this point, this read might have been easier to digest had it started with the section &quot;object this.&quot;
评论 #8714710 未加载
vogover 10 years ago
The &quot;this&quot; keyword in JavaScript is a well-known anti-pattern. Although it can be explained with a few rules, it becomes cumbersome quickly.<p>The anti-pattern around &quot;this&quot; is well-known for decades. For example, SICP explicitly mentions that anti-pattern. Of course, it doesn&#x27;t refer to JavaScript, but to some other old programming language which had a keyword with very similar issues. I think it&#x27;s not a hyperbole to say that in this regard, the JavaScript&#x2F;ECMAscript language designers haven&#x27;t learned from the past.<p>The main issue is that &quot;this&quot; violates lexical context. Fortunately, the lexical context is easily restored by declaring a normal variable, usually named &quot;me&quot;, and using the fact that variables have always lexical scope in JavaScript (as it should be):<p><pre><code> var me = this; someFunctionWithCallback(function() { me.something(...); }); </code></pre> Another workaround is adding a &quot;scope&quot; argument to functions which take callbacks:<p><pre><code> someFunctionWithCallback(function() { this.something(...); }, this); </code></pre> Or:<p><pre><code> someFunctionWithCallback({ callback: function() { this.something(...); }, scope: this });</code></pre>
评论 #8753903 未加载
评论 #8715892 未加载
评论 #8716797 未加载
amitambover 10 years ago
I understood these concepts by reading this book. It is great book for anyone wanting to go from intermediate to advanced or may be even beginner to advanced level<p><a href="http://www.manning.com/resig/" rel="nofollow">http:&#x2F;&#x2F;www.manning.com&#x2F;resig&#x2F;</a><p>You can go on using Javascript for years without understanding some basic concepts like &quot;value of this does not depend on where that function is defined but the way it is called&quot;.
jpolitzover 10 years ago
This topic has come up before on HN, and I ended up writing up a pretty comprehensive list of ways this can be bound, with references to the spec:<p><a href="https://news.ycombinator.com/item?id=4986125" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=4986125</a>
pavlovover 10 years ago
Maybe, rather than overriding the C++ &#x2F; Java keyword with a different meaning, <i>this</i> should have been called something completely else in JavaScript. I think <i>context</i> would have been more descriptive.<p>But it&#x27;s about 17 years late for that...
mambodogover 10 years ago
Another way of thinking about it is that it&#x27;s kinda like Function.prototype.call is being used implicitly at the call site to set the &#x27;context&#x27; (the &#x27;this&#x27; value):<p><pre><code> &#x2F;&#x2F; assuming in each case var o = {} var o2 = {} var fn = function(){} &#x2F;&#x2F; 1. bare function call fn() &#x2F;&#x2F; this == undefined in strict mode, global in non strict mode. &#x2F;&#x2F; 2. calling with Function.prototype.call fn.call(o) &#x2F;&#x2F; this == o &#x2F;&#x2F; 3. &#x27;method&#x27; call (calling an object&#x27;s function property) o2.fn = fn o2.fn() &#x2F;&#x2F; this == o2 &#x2F;&#x2F; equivalent to fn.call(o2) &#x2F;&#x2F; 4. calling object&#x27;s function property with Function.prototype.call o2.fn = fn o2.fn.call(o) &#x2F;&#x2F; this == o &#x2F;&#x2F; 5. new var o3 = new fn() &#x2F;&#x2F; this = o3 &#x2F;&#x2F; equivalent to var o3 = Object.create(fn.prototype) fn.call(o3) &#x2F;&#x2F; 6. calling function bound with Function.prototype.bind var fn2 = fn.bind(o) fn2() &#x2F;&#x2F; this == o &#x2F;&#x2F; equivalent to var fn2 = function(){ fn.call(o) } fn2() &#x2F;&#x2F; 7. calling object function property which is a bound function o2.fn = fn.bind(o) o2.fn() &#x2F;&#x2F; this == o &#x2F;&#x2F; equivalent to o2.fn = function(){ fn.call(o) } o2.fn() </code></pre> Basically you should think of functions (and &#x27;methods&#x27;) as not being intrinsically bound (as in binding-of-&#x27;this&#x27; bound) to anything.<p>If you think of a &#x27;method&#x27; (function property) as being bound an object purely by being &#x27;attached&#x27; to it then you are gonna have a bad time. Instead, think of binding of &#x27;this&#x27; as usually only happening at call time, to the thing you are &#x27;calling the function off of&#x27;.<p>In reference to case 1 (bare function call), this is the same behaviour which occurs when as defining an anonymous function inside a function which has &#x27;this&#x27; set. Just don&#x27;t use &#x27;this&#x27; in this case, it doesn&#x27;t make sense. Defining a _this or self variable in the parent function is the standard practice to deal with this case, or in ES6, Coffeescript etc. you have the =&gt; fat arrow to implicitly do that for you.
madlynormalover 10 years ago
Check out Kyle Simpson&#x27;s &quot;You don&#x27;t know JS&quot; if you really want a clear understanding on &quot;this&quot; and how it relates to objects in Javascript. <a href="https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;getify&#x2F;You-Dont-Know-JS&#x2F;tree&#x2F;master&#x2F;this%...</a>
wycatsover 10 years ago
I once wrote a description of `this` from the perspective of `call` as a &quot;primitive&quot;: <a href="http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/" rel="nofollow">http:&#x2F;&#x2F;yehudakatz.com&#x2F;2011&#x2F;08&#x2F;11&#x2F;understanding-javascript-fu...</a><p>It seemed relevant. :)
bshimminover 10 years ago
Tony Hoare has famously described null references as his billion dollar mistake. Given how often we see articles attempting to explain `this` in JavaScript (indicative, therefore, of the general level of confusion around it), I wonder if perhaps we should be starting to think about `this` in similar terms.
jqmover 10 years ago
I liked this article. Yes, it was a bit repetitive and had lots of examples. Which is why I like it.
john2xover 10 years ago
Here&#x27;s[1] an open-source book dedicated to &quot;this&quot;.<p>[1]: <a href="https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;getify&#x2F;You-Dont-Know-JS&#x2F;tree&#x2F;master&#x2F;this%...</a>
hngiszmoover 10 years ago
As I&#x27;m doing my first serious projects in JS now, I&#x27;m thankful for the article and the simplifying corrections here. Java.this != JS.this
namuolover 10 years ago
Great reference doc! Grotesquely thorough.
robin_carryover 10 years ago
Nice article...actually it helps in explaining new colleagues in our team. The link to examples is also good.
chcokrover 10 years ago
I&#x27;d say that one possible solution is to not use `this` at all. Same goes for `new` for that matter.
dennisbestover 10 years ago
In other words, &quot;this&quot; is nuts!