Removing JavaScript's 'this' keyword makes it a better language
medium.freecodecamp.org
medium.freecodecamp.org
The web would be a better place if Javascript developers put all of their effort trying to write code in the language they would rather be using into writing better code in the language they are using.
> The web would be a better place if Javascript developers put all of their effort trying to write code in the language they would rather be using into writing better code in the language they are using.
Right, but then no one would use “this”...
It is, because avoiding it requires extra and unnecessary abstractions. "this" is a fundamental part of the language regardless of the paradigm. If you want to use a functional style in javascript, you have to accept that it isn't a pure functional language, and do so using "this," not avoiding it.
> If you want to use a functional style in javascript, you have to accept that it isn't a pure functional language, and do so using "this," not avoiding it.
This is nonsense. You don’t have to do anything at all to program in a functional style in JS. You don’t need to use “this” and I can’t even imagine how using “this” would be helpful to that end.
I mean, the premise of the posted article is that javascript developers should avoid using "this" for functional (and OOP) programming, but OK... I can't tell if you disagree with me here, or the author, or what.
JS has gone through lots of careful language changes (strict mode, arrow functions, classes), and tools like ESLint and TypeScript help limit confusing parts of the language, and I think it's worthwhile to put at least some effort into making JavaScript better rather than just accepting it.
Composition does not face these issues because instead of a parent class, the outside class's API is not beholden to the inside class's API.
Similarly, in prototypal inheritance, you get to specifically control API by binding or calling 'this' to any choice of object, or select methods to put in other objects, or even replace a method of an object with another method of the same name at runtime, or declare new fields and methods on objects at runtime. This makes prototypal inheritance very open for extension in a way that class-based inheritance cannot be. The downside to this is that JS does not have language features that sufficiently guarantee that an object is closed for modification: in class-based languages classes are a language feature that give a sort of guarantee about the API of an object, but JS objects have no mechanism as powerful as that, and you will need to roll your own. Hence the eventual development of languages and extensions to JS like TS, Reason, Flow that offer these guarantees that transpile to JS.
None of this sounds like a good idea to me.
1.) `this` should only be used inside a class method.
2.) Never use `someClassInstance.someMethod` as a value (invoking it is ok, but accessing it without invoking it isn't). Make it a bound method using class field syntax or wrap it in an arrow function and invoke it there.
3.) Never use `function` syntax for function expressions (e.g. callbacks), only arrow functions. Callbacks should never need `this` because the information they need should be provided via arguments.
Fortunately, modern tools make this pretty easy to follow. #1 is mostly enforced naturally by TypeScript; if you try using `this` in a plain function, it will yell at you unless you explicitly annotate what `this` means. #2 is enforced by the TSLint rule no-unbound-method. #3 is enforced by the ESLint rule prefer-arrow-callback. With these rules, even beginners on my team have rarely/never made `this`-related JS mistakes.
Subscribe here [link].
Like my post [link].
My Amazon wishlist [link].
Follow me on Twitter [link].
Any function call in JS is a short form of this:
func.call(its_this,arg0,arg1)
In the same way as arguments at call site are passed through named parameters into function body, `this` parameter is passed to the function from outside.That stands true for any language that uses this keyword. C++, Java, etc.
No rocket science in all this.
* In Java, their solution is to simply not have first-class functions, so the syntax isn't possible. Method invocation (`myInstance.myMethod()`) is a special syntactic form; it's not just a property access and function invocation. There's a special `myInstance::myMethod` syntax that's like a lambda and behaves as expected, including allocating a new instance each time it's used.
* In Python, `myInstance.myMethod` always allocates a new function object, just like `myInstance.myMethod.bind(myInstance)` would do in JS. This avoids the mistakes from JS, but is a bit magical and inefficient (though I'm sure the implementation can optimize it). For example, `arr.append is arr.append` is false because simply accessing a method creates a new function object, so you'll get two different function objects. Still, this has a certain elegance because method invocation doesn't need to be seen as a special syntax like it is in Java and JS.
* In JavaScript, method invocation (`myInstance.myMethod()`) is a special syntactic form like in Java that passes along `this`, but `myInstance.myMethod` is also allowed and drops `myInstance`. This is efficient if you didn't care about `this`, but can be surprising to beginners and requires more care than in other languages.
To compare these: Python and JavaScript are flexible because they allow dot syntax, i.e. methods as first-class functions. JavaScript and Java are efficient because they don't do an unnecessary allocation unless you opt into it. Python and Java are harder to misuse because they don't provide a syntax for accessing `myMethod` without `myInstance` bound to it.
(start around 35:40)