1

I have this code:

let bar = () => {
  let x = 5; 
  console.log(this.x)
}

bar();

It does not work. I also have this code:

let bar = () => {
  this.x = 5; 
  console.log(this.x)
}

bar();

It does work. I want to make sure I understand why. As I understand it, simply declaring a variable within a function does not make it a value on the function object. Only when declaring this.___ = ____ does it actually become a value on the object.

...is that right?

J Seabolt
  • 2,576
  • 5
  • 25
  • 57

1 Answers1

2

There are two types of functions in JavaScript with respect to this: arrow functions and non-arrow functions.

function () {}

For non-arrow functions, you can think of this as just another parameter. Where a typical parameter would be set by passing an argument:

function foo(x) {
    return x;
}

foo(1);  // returns 1

the this parameter is set by how the function is called:

function foo() {
    return this;
}

var obj = { foo: foo };


foo();         // returns undefined, because it’s not one of the following
               // special forms

obj.foo();     // returns obj, because the function was called with dot notation

obj['foo']();  // returns obj, because bracket notation and dot notation
               // work the same

foo.call(1);   // returns 1, because a function’s `call` method
               // sets `this` explicitly
new foo();     // returns a new object of type `foo`‽ read up!

Every non-arrow function has this implicit parameter called this. The top scope, outside any function, also has a this. It can be a few different things, depending on your environment; you can safely ignore it.

() => {}

Arrow functions don’t have the implicit this parameter. They use the this from their containing scope, like any other variable. In other words, in complete opposition to non-arrow functions, how they’re called doesn’t matter at all; it’s about where the () => { … } is located.

// `this` outside `foo`…

const foo = () => {
    // is the same as `this` inside `foo`. always.
    return this;
};

Now, tying it all together, your arrow functions are in the top scope, outside of any other function. That means they have whatever this was in the top scope. If that isn’t undefined, you can set values on it, like you’re doing with this.x = 5; in an arrow function. It’s the same this every time, though, and it’s certainly not referring to “the function object”.

As for the first example: declaring variables, like with let x = 5;, has nothing to do with this at all.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Nice and concise. I wish this would be part of https://stackoverflow.com/q/3127429/218196 though. – Felix Kling May 31 '18 at 18:25
  • @FelixKling: Yeah, I don’t really know where to put the abridged versions of these things compared to the detailed spec answers. Another answer to that question…? – Ry- May 31 '18 at 18:33