6 ms·
Javascript Fundamentals: ‘this’ keyword
- sonnyblarney 8y agoThe answer to every question in this article, and any 'quiz' on how to use the arbitrary and ridiculous 'this' in JS is simple: use TypeScript.
- deleted 8y ago[deleted]
- n_e 8y ago« this » works exactly the same in TypeScript.
- sonnyblarney 8y agoI realize, but it's more of a reaction to the inanity of JS, moreover, since I've started using JS, I've never once had any issue with 'this' - the way one constructs code often in TS is simply quite different i.e. it's really not just 'JS with typing' even if you want it to be just that, usually it's not.
- sdegutis 8y agoMy TS code looks almost identical to my JS code, but with types. Some JS patterns are a little harder to express in TS, but only because they're inherently a little more difficult to implement correctly. Things like higher-order functions (and HOCs).
- sonnyblarney 8y agoMy TS code looks like Java or Swift. If it's more than a quick function on a web page, I'll never write JS again.
- trgv 8y agoIf your .ts code differs massively from your .js code you have no one to blame but yourself.
- sonnyblarney 8y agoBlame? Not only is this how I want it, I think it's the obvious and natural progression of Typescript code. Typescript is not just 'typing' for JS, it encourages much cleaner abstraction, modularization etc. than JS. My first Typescript exposure was a re-write of several thousand lines of JS code. After a little bit of 'adding typing' I realized there were much better ways to organize information. The result was powerful - what was once a near hairball of code, was now magnificently cleaner, easier to read, easier to re-factor, easier to maintain. That experience not only validates the existence of TS but strongly highlights the limitations of JS which has always been a deeply problematic language, full of pot holes and weirdness, and though it's fully understandable why the language evolved how it did - that's no justification for it's ugly failings which cause existential inefficiency in many situations. Though 'adding typing to JS' might be a good start for using Typescript in any given scenario - anyone only doing that is missing a bigger opportunity.
- sdegutis 8y agoI think that's because TS lets you see patterns in your data and code that were "invisible" in JS. You could still write clean code in JS, you just have to be able to see all that implicit structure. Spaghetti code is spaghetti code with or without types, it's just easier without types.
- sonnyblarney 8y agoThat's totally true, but it's pretty much the point of a programming language - to enable and facilitate intelligent organization of logic.
- trgv 8y agoThe reason your posts in this thread are so irritating is because TS has all the same junk people hate about JS. You say things like JS is "deeply problematic" and "full of pot holes and weirdness" but you don't address how TS has fixed any of these problems. (Hint: it hasn't. Fixing the language is totally beyond the scope of TS). Typescript provides concrete benefits. Maybe it also provide some benefits that aren't so concrete, like encouraging developers to think about how they're representing data earlier rather than later. But it doesn't "fix the language".
- digitaLandscape 8y agoThis would have been a good post in 2014 but it shouldn't be relevant to any JavaScript developers in 2018. Arrow functions don't have `this`, and `...` syntax is simpler and as efficient as using `apply`. You only still need to use `function(){}` for generators and custom constructors, which are rare.
- sdegutis 8y agoVery relevant in 2018. React uses ES6 classes (inherit from React.Component) so you're very often using `this` in React. In fact it's still a major source of confusion still for many devs like me, especially when you create and pass callback functions. I've been meaning to write a blog post on this so maybe this is the motivation I needed.
- digitaLandscape 8y agoJust use arrow functions for your callbacks! This is trivial. Don't create a problem that doesn't exist.
- sdegutis 8y agoThis results in extra renders for an entire component chain, because comparing two arrow functions will always be different whereas comparing two pre-defined functions will always be the same. Hence React's recommendation to use 'bind'.
- gear54rus 8y agoWhat I don't get is why the React guys don't just call the passed functions with 'this' being the component, which seems like the most common use case. If you need to override this, you could indeed use bind (it's not overridable after that AFAIK so no logic is required from React side).
- sdegutis 8y ago
- Kagerjay 8y agohonestly "this" is such a stupid construct in javascript, there's way too many obscure and unuseful edge cases to memorize.
- expertentipp 8y agoNot knowing this 8 years ago in interviews was the same disqualifying as not knowing nowadays what is the latest Angular version and why is it incompatible with the previous version. The difference is that "this" is still relevant - just hit F12, enter "this", and hit <ENTER>.
- anonytrary 8y agoIf you're getting asked about Angular in your interviews, its probably because you applied to a front-end job where they explicitly told you that you will be using Angular 8 hours a day.
- expertentipp 8y agoFront-end is not synonymous with Angular at all.
- anonytrary 8y agoThat's a straw man. I was talking about this: > front-end job where they explicitly told you that you will be using Angular 8 hours a day
- 131hn 8y ago« this » is « the thing on the left side of the dot ». (that’s not always true, nor a complete definition - but it helps me a lot in understanding the whole thing)
- stupidcar 8y agoI think the main reason "this" is considered confusing is that many programmers learning JS have already spent years coding in Java or C#. They expect it to work the same, then get frustrated when it doesn't. But the reason it doesn't is due to the fact that functions in JS are first-class, and don't intrinsically belong to a particular class and object instance they way they do in those languages. As such, the context represented by "this" has to be more fluid in JS. That's not to say that the design of "this" is perfect. And it doesn't help that JS' syntax was designed to resemble C-family languages that it differs from significantly. But nor it is some entirely arbitrary and illogical flaw. If you take the time, it's possible to gain an intuitive grasp of how functions and "this" work in JS. But instead, learners are too often told that "JS is quirky" by others who also have come to it from Java / C#, and never move past memorizing to a list of these "quirks" to genuine proficiency. They then grumble whenever they need to work on a JS codebase, because their incomplete understanding makes it feel like they're standing on quicksand. Soon such devs fall into a circular trap: They don't like coding in JS because it feels weird and unintuitive. And they don't take the time to learn about it more deeply because they don't like coding with it, and don't want to waste time learning about something they dislike. But since they have to code with it, because it's part of their job, they just stumble along, hacking away and getting frustrated when things don't work, then come onto Hacker News and blow off steam about what a garbage language JS is.
- aphextron 8y ago>I think the main reason "this" is considered confusing is that many programmers learning JS have already spent years coding in Java or C#. They expect it to work the same, then get frustrated when it doesn't. But the reason it doesn't is due to the fact that functions in JS are first-class, and don't intrinsically belong to a particular class and object instance they way they do in those languages. As such, the context represented by "this" has to be more fluid in JS. As someone who’s “native” language is JS, I think that’s spot on. I never had the baggage of thinking in terms of Java or C++, and so I couldn’t understand why people would get confused over “this” because it was fundamental to learning the language and thus to my mental model of programming in general.
- 8y ago
- lucisferre 8y agoI could summarize the `this` keyword in one sentence: Avoid it.
- paol 8y agoIt's really frustrating that the ECMA people didn't define class methods to always be bound just like arrow functions. Like arrow functions, classes are a new syntax so there are no backward compatibility concerns. That said, having two different semantics based on which syntax you happened to use to define a function is almost as big a programmer trap as the original problem. It just goes to show there are no good solutions to fundamental language design errors.
- aphextron 8y ago>It's really frustrating that the ECMA people didn't define class methods to always be bound just like arrow functions. This is a huge annoyance because I never really know where to bind my events. It always ends up just being an awkwardly placed "bindEvents" call somewhere in the init function.
- jaunkst 8y agoThis is fine. It's not confusing. Don't expect JavaScript to be Java.
- anonytrary 8y agoThis example is needlessly confusing: const a = { b: 42, c: function() { return this.b; } }; (a.c || [])(); // 1 (a.c)(); // 2 (1, a.c)(); // 3 He's trying to illustrate that an expression returns a reference to the (unbound) function. This line "(a.c || [])()" is bothering me -- why on earth would this line exist in any program? Are we trying to throw a type error on purpose? Maybe "(a.c || (()=>{}))()" would have been more appropriate. I spent about 5 minutes wondering why each line returned 1, 2 and 3 respectively, when they should be returning the global value of b. If you are going to be showing obscure, tricky examples of Javascript, the last thing you want to do is have superfluous comments in your code. Follow comment conventions for the sake of your readers' sanity. This would have been much less confusing: const a = { b: 42, c: function() { return this.b; } }; (a.c || (() => {}))(); // undefined (a.c)(); // undefined (1, a.c)(); // undefined
- pitaj 8y ago`(a.c)()` is not undefined, it's 42
- anonytrary 8y agoNice catch, I should edit that but it's too late. I think my point still stands, however...
- wruza 8y ago>This line "(a.c || [])()" is bothering me -- why on earth would this line exist in any program? A variation of it is valid for method selection, such as: (cond ? a.foo : b.bar)(); or, for method fallback: (a.foo || a.fooDefault)(); Neither does work in js, though.
- anonytrary 8y agoThis is useful and works with functions that don't use `this` (like arrow functions).
- werkjohann 8y agoJavaScript Fundamentals: it’s “JavaScript”, not “Javascript” :P