
What does ‘that = this’ in JavaScript mean? - sidthesloth
https://dbwriteups.wordpress.com/2017/04/08/what-does-that-this-in-javascript-mean/
======
krptos
I prefer using `self` rather than `that`, for caching `this`.

Must be because I have a strong python background, but generally I find "self"
makes more sense than a wild "that"!

~~~
karol
By using `self` you shadow a global variable which is a reference to the
current context (window object) in which the code is executed.

~~~
lexicality
Which should be accessed by window.self anyway so it doesn't really matter?
There are so many poorly named global variables (top etc) that worrying about
shadowing them seems meaningless.

~~~
amorgaut
It matters when you are running in workers in which case the window object
does not exists

------
twiss
_Note: Arrow functions cannot help us when the function is defined on the
object literal as it will resolve to the enclosing lexical scope, which in
this case is the global scope._

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...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this)

~~~
sidthesloth

        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.

~~~
nawitus
If you add "var that = this;" to printName function the printNameReference
still doesn't work.

------
seattle_spring
For my company, `that = this` means that your code review gets marked as
"Revision required".

~~~
kahnpro
Same here. Bind your functions properly!

------
adolph
Since nobody has mentioned it yet, my first introduction to that = this; was
JavaScript: The Good Parts, Unearthing the Excellence in JavaScript by Douglas
Crockford

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.

[http://shop.oreilly.com/product/mobile/9780596517748.do](http://shop.oreilly.com/product/mobile/9780596517748.do)

------
amelius
Title should be "var that = this".

Without "var", you're assigning to a global variable which you don't want in
most cases.

~~~
chrisseaton
I'm not a JavaScript expert so I may be wrong, but I don't think that's right
is it?

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?

~~~
jonreem
No, GP is correct. If you omit the `var` (or `let`/`const` in es6) then you
are implicitly assigning a property on the global object (`window` in the
browser), in essence setting a global variable. Never omit `var`.

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.

~~~
sopooneo
I agree with the way you've responded. But there can be a case where omitting
var on a variable definition will _not_ assign it on the global object. That
is, if you hit a variable by the same name as you go up the scope stack, you
will just overwrite that variable's value. Example:

    
    
      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 defined

------
karol
This an ugly convention. By always using `that` you lose an opportunity to
create a meaningful variable name which would be more descriptive. Why not
use?

    
    
        var widget = this
    

Besides using more functional approach and arrow functions you can free up
your code from lining methods via this keyword.

~~~
dntrkv
That's way more confusing. At least with `that`, you know it is pointing at
the current instance. If you see `anyOtherVariableName` you have to know what
it was assigned.

------
sidthesloth
This a follow up post on how to replace 'that = this' assignments with arrow
functions: [https://dbwriteups.wordpress.com/2017/04/14/replacing-
that-t...](https://dbwriteups.wordpress.com/2017/04/14/replacing-that-this-
assignments-in-javascript-with-arrow-functions/)

------
tabeth
Is it a poor pattern to use #bind a lot instead of this or that? I tend to put
most of the code in procedures like functions and bind it to whatever context
I need, if not the regular _this_.

~~~
OSButler
If you're using React and you're not using arrow functions, then it's very
common to see bind() references.

------
cerved
I stopped using this altogether and it makes my code better

~~~
boubiyeah
It's absolutely useless anyway unless you're trying to slightly optimize cpu
and memory usage for at least hundreds of instance creations. Typically this
scenario would be found in libs, not in application code.

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.

~~~
sideshowb
How do you factor out "this" in cases where methods and instance data
logically belong together?

~~~
boubiyeah
1) Either use a functional style like beaconstudios said where it's perfectly
normal to separate the data and the processing.

2) Or if you want to keep an OO style, use the module pattern with private
functions closing over the data.

------
Animats
If you have closures, you can simulate objects. In many different ways, most
of them bad. If you have an interpreter with decent variable semantics, you
get closures. That's how LISP did objects in the 1980s, before people knew
better. Javascript somehow got it from there.

Why do we have to keep reviving the bad ideas?

~~~
lispm
> you get closures. That's how LISP did objects in the 1980s, before people
> knew better

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](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...](http://www.unlambda.com/lispm/lmi-
source/extract/dj_full/l/objectlisp/)

In

[http://www.unlambda.com/lispm/lmi-
source/extract/dj_full/l/o...](http://www.unlambda.com/lispm/lmi-
source/extract/dj_full/l/objectlisp/obj.lisp.155)

you can see that objects in Object Lisp were implemented by using structures
(aka records), not closures.

------
crgwbr
Despite writing ES6 with arrow functions, I find that I prefer writing `const
self = this` than relying arrow-function lexical scoping. Maybe it will change
over time, but for now that way seems to make he intent far clearer and less
likely to mess up in a future refactoring.

~~~
z3t4
To make it more clear, you can use names. For example:

    
    
      function Car() {
        const car = this;
        function foo() {
           car.engine = "v8"; // vs self.engine
        }
      }

~~~
nkkollaw
Not much clearer, if not less.

var self = this; and var that = this; are the standard way and the intent is
understood right away.

~~~
monkpit
That's like, your opinion, man.

~~~
nkkollaw
Yup. All the stuff I say is definitely my opinion.

I'm not the one who invented JavaScript or anything like that.

------
Vanit
I try to omit this convention by promises or bind() when possible, but
sometimes when using 3rd party libraries it's a necessary evil.

------
golergka
Is there a single instance in real JS code where it's this binding is actually
useful?

~~~
gbuk2013
Yes - if you want to use this inside a callback within your function.

~~~
golergka
Oh, I wasnt being clear. I meant the default binding behaviour, not using
.bind().

~~~
gbuk2013
One common example would be to refer to instance properties of an object from
a method that is attached to the object's prototype.

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).

------
nunez
_this_ should never be _that_ complicated.

------
jaypaulynice
I use var _this = this

------
oblib
Nicely done!

Thank you for sharing!

------
DonHopkins
It means JavaScript was a poorly designed language.

~~~
ams6110
Not sure I'd go that far but it definitely has its warts, like all languages,
and developers need to understand what they are.

~~~
DonHopkins
Don't get me wrong: I love JavaScript, I write piles of it all the time, and I
said "was" not "is" because it's been vastly improved since it was originally
badly designed, but I still get screwed by accidentally using "this" in the
wrong context.

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.

