0

never fully understood lexical scoping in context of arrow functions and normal functions

this.thisGlobalVariable = 200;

function normalFunction() {
    this.thisVariable = 100;
}

function normalFunctionTwo() {
    console.log(this.thisVariable); // 100
    console.log(this.globalVariable); // undefined
}

let anonymousArrowFunction = () => {
    console.log(this.thisVariable); // undefined
    console.log(this.thisGlobalVariable); // 200

}
normalFunctionTwo();
anonymousArrowFunction();

so since anonymousArrowFunction is an arrow function, it's lexical (its scope is the context in which it was created in) here, it'd be the global scope as it's able to access this.thisGlobalVariable? whereas normalFunction and normalFunctionTwo as normal functions would create its own this, in its own scope? how is normalFunctionTwo able to access this.thisVariable that was defined in normalFunction?

totalnoob
  • 2,131
  • 5
  • 27
  • 54
  • "how is normalFunctionTwo able to access this.thisVariable that was defined in normalFunction?" It isn't able to access it. Did you bother to run the code you posted? Push the blue button. `console.log(this.thisVariable);` outputs `undefined` both times it's executed. – gforce301 Sep 14 '18 at 15:06
  • Did you ever run `normalFunction()`? – Barmar Sep 14 '18 at 15:11
  • Possible duplicate of [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – FK82 Sep 14 '18 at 15:22

3 Answers3

1

For the normal functions, the value of this is determined at the time the function is called. You're calling the functions without any context, so this is set to the window object (in non-strict mode). Since the functions are all interacting with the same window object, they can see eachother's handywork (though you have some bugs in your sample code which are making it not work correctly)

There are other ways the function might be invoked, and they will result in different values of this. For example, suppose i stick a function in an object and call it by referencing that object:

this.val = 'from window';

function doStuff() {
   console.log(this.val);
}

const myObj = {
  val: 'from object',
  log: doStuff
}

console.log(doStuff === myObj.log) // <-- they're literally the same function
doStuff(); // <-- this is set to the window object
myObj.log(); // <-- this is set to myObj
Nicholas Tower
  • 37,076
  • 4
  • 43
  • 60
1

"normal functions" determine their context by how they were called, so:

 context.method();

calls method with this pointing to context. Now you do

 normalFunctionTwo();

that calls the function without any context, and then the context defaults to the window object. So this inside normalFunctionTwo (and also outside of it) points to window. There is no difference to arrow functions in this case.

Jonas Wilms
  • 106,571
  • 13
  • 98
  • 120
1

You're misunderstanding something about how this is being determined: quote from MDN

In most cases, the value of this is determined by how a function is called. It can't be set by assignment during execution, and it may be different each time the function is called. ES5 introduced the bind method to set the value of a function's this regardless of how it's called, and ES2015 introduced arrow functions which don't provide their own this binding (it retains the this value of the enclosing lexical context).

The value of this is not being created by a function and you cannot directly assign to it. Instead this is being resolved before execution (see here). This is why Function.apply, Function.call and Function.bind exist which may be used to explicitely set this.

The difference between a "normal" function declaration and an arrow function declaration is that in the second this is automatically bound to the enclosing lexical context.


In your code snippet btw, this always references the global scope.

FK82
  • 4,517
  • 3
  • 25
  • 36