What does ‘that = this’ in JavaScript mean?
dbwriteups.wordpress.com
dbwriteups.wordpress.com
Must be because I have a strong python background, but generally I find "self" makes more sense than a wild "that"!
So if my "this" object is actually an AwesomeTableWidget instance, I might do:
var table = this;
I like the bit of extra documentation it provides... Or maybe this is just a remnant of all the C code I've written over the years, where it's common to have an object pointer as the first argument to a function and it's usually named like this.This is not true. With an arrow function, the example prints "Object Name". MDN says: "An arrow function does not create its own this context, so this has its original meaning from the enclosing context." [1]
(The "enclosing context" in this case refers to the context in which the arrow function was created, not the context in which the function in which the arrow function was created was created.)
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
var name = "Global Name";
var obj = {
name : 'Object Name',
printName : function() {
setTimeout(() => {
console.log(this.name);
}, 2000);
}
};
obj.printName(); //prints "Object Name"
var printNameReference = obj.printName;
printNameReference(); //prints "Global Name"
You will see that "Global Name" will still be printed out. The reason is because arrow functions take the enclosing lexical scope, and the arrow function to setTimeout in the example is created each time the printName function is invoked. The printNameReference() invocation sets the scope of the printName function to global because of the way it is invoked and hence the arrow functions to setTimeout will also take this scope.Changing the printName function itself as arrow function does not help either.
var obj = {
name : 'Object Name',
printName : () => {
setTimeout(() => {
console.log(this.name);
}, 2000);
}
};
The above code will again set the printName function to the enclosing global scope, because that is where obj is declared.Well worth a read for understanding the differences and relative powers of a prototypical language and how to get it to behave almost like a classical one. I think the one big thing it missed was immediately envoked function expressions.
Without "var", you're assigning to a global variable which you don't want in most cases.
function foo() {
'use strict';
bar = 5; // Error (maybe)
window.bar = 6; // No error
} that = this; var that;
would work. JavaScript!If you are in a function scope (which you would be in the context of this article as we're talking about what the receiver is at different points) then variables assigned without any modifier are defined as locals, in the scope of that function. They are hoisted to the function scope, out of any block scope, unless you use 'var', but they're still locals aren't they?
If you are in a function scope, `var` declarations are hoisted to the top of the function scope, outside of any block scope, as you described. `let` and `const` declarations from es6 are block scoped. Personally I highly recommend never using `var` and simply adopting es6 and using `let` and `const`, preferring `const`, everywhere as they have significantly simpler and more intuitive semantics.
function f1(){
var v = 'val';
var f2 = function(){
v = 'inner'; // will not hit global scope
}
f2();
console.log(v);
}
f1();
console.log(v);
output: val
Uncaught ReferenceError: v is not definedFrom https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- "We're not going to have declarations in our language. First use defines a variable".
- "We need some way to define local variables. But if we make that the default, existing code will break. So the default has to be global."
- Embrace the pain.
There are variants on this theme. Python is local by default. Go has variable creation by assignment with ":=", but with weird semantics for multiple assignment.
Other classic mistakes are "we don't need a Boolean type; 1 and 0 are enough", and "there's only one kind of integer". Fixing those later always sucks.
var widget = this
Besides using more functional approach and arrow functions you can free up your code from lining methods via this keyword.I completely ignore this, prototypes, classes, Function.prototype.bind, etc. Code is much cleaner and easy to follow for devs of all skill level.
Also, even if you like these features, var that = this is unneeded if you use a transpiler and have access to the more modern JS constructs like arrow functions.
2) Or if you want to keep an OO style, use the module pattern with private functions closing over the data.
Why do we have to keep reviving the bad ideas?
That one can use closures for objects was demonstrated with Scheme in the 70s. See for example: Scheme: An Interpreter for Extended Lambda Calculus". MIT AI Lab. AI Lab Memo AIM-349. December 1975.
http://library.readscheme.org/page1.html
It's also a typical topic in education to show how to use closures to implement a primitive object system, similar how one learns to 'implement' numbers in pure lambda calculus.
But actual object systems in Lisp from the 70s/80s mostly did not use closures as objects. None of LOOPS, Flavors, CLOS, KRL, KEE, FRL, ... uses closures for their implementation. Even in 'Object Lisp', which is relatively close to Javascript's objects, they don't use closures:
http://www.unlambda.com/lispm/lmi-source/extract/dj_full/l/o...
In
http://www.unlambda.com/lispm/lmi-source/extract/dj_full/l/o...
you can see that objects in Object Lisp were implemented by using structures (aka records), not closures.
function Car() {
const car = this;
function foo() {
car.engine = "v8"; // vs self.engine
}
}var self = this; and var that = this; are the standard way and the intent is understood right away.
I'm not the one who invented JavaScript or anything like that.
Actually I think using bind() would be a very unusual thing, but that could just be my style of writing code (I don't think I've ever used it in any code I have written over the years).
Thank you for sharing!
It's such an easy accident to make, and it's so hard to see, because when you're looking at code you wrote, you see what you meant to write, instead of what's actually there. Programming languages are user interfaces, and "this" is a user interface dark pattern, an unforced design mistake that doesn't make the language any more powerful, but lays a deadly trap for beginners that also bites pros.
It's tricky to understand and hard to explain (this is actually a dynamically bound keyword, not a lexically bound variable), so it's fodder for the thousands of blog posting explaining it like the one we're discussing.