3

I found the following code in this site (excluding console.log stuff):

console.log((function(x, f = () => x) {
  var x;
  // console.log(this.x,x); // undefined 1
  var y = x;
  x = 2;
  return [x, y, f()];
})(1)); // [2, 1, 1]

Apparently f() having the same result as x which are being passed in parameter. And if you uncomment console.log(this.x,x) it would show undefined and 1.

I've read the following:

What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript?

What is the difference between () => {} and function() {} in react-native javascript?

What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?

What does this refer to in a JavaScript function?

How does the "this" keyword work?

this - JavaScript | MDN

My question is why did this.x return undefined even if you set the var x = 2? Refer to the following snippet:

console.log((function(x, f = () => x) {
  var x = 2;
  console.log(this.x,x); // undefined 2
  var y = x;
  x = 2;
  return [x, y, f()];
})(1)); // [2, 2, 1]

and if you remove var x

console.log((function(x, f = () => x) {
  console.log(this.x,x); // undefined 1
  var y = x;
  x = 2;
  return [x, y, f()];
})(1)); // [2, 1, 2]

does this.x doesn't point to the parameter or local variable?

Shinjo
  • 677
  • 6
  • 22
  • 4
    *"does `this.x` doesn't point to the parameter or local variable?"* - no, it is neither a parameter or a local variable and it does not point to any of them. `this.x` is a different thing and it is `undefined` because you never assign a value to it. – axiac Apr 09 '19 at 06:34
  • Actually, even if I did pass the value like in the previous example `var x=2` `this.x` still, return `undefined`. – Shinjo Apr 09 '19 at 06:35
  • 3
    Because `x` and `this.x` are different things. – axiac Apr 09 '19 at 06:36
  • Why *would* `x` and `this.x` be the same? `this` is the functional context, so `this.x` would take *the `x` property from that context*. If your function is defined in the global scope, then `this === window`. However `var x` will declare a new variable that is *not* exposed to the global scope. Hence, it would never be the same as `this.x` – VLAZ Apr 09 '19 at 06:40
  • I'm confused. Would that mean `this` only would refer to global context? And would *never* affect local (functional context)? – Shinjo Apr 09 '19 at 06:42
  • Are you confusing context and scope? Because `this` is the *context*. At a basic level, it's an object which holds values. The *scope* can be functional or global. For `let` and `const` there is also block scope. But context and scope are different concepts. – VLAZ Apr 09 '19 at 06:44
  • Ah, I think so. Thanks for clarifying that VLAZ I found myself a good resource [here](http://ryanmorr.com/understanding-scope-and-context-in-javascript/) which explained what you reply earlier. – Shinjo Apr 09 '19 at 06:56
  • Based on [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) which quote [11.1.1 The this keyword](https://ecma-international.org/ecma-262/5.1/#sec-1): "The `this` keyword evaluates to the value of the ThisBinding of the current execution context." Does that mean function scope `var x` doesn't count as context? – Shinjo Apr 09 '19 at 07:18
  • 1
    @Shinjo I don't know, but it's definitely not a ThisBinding. – melpomene Apr 09 '19 at 07:27

2 Answers2

1

From the book You don't know JS by Kyle Simpson

this is actually a binding that is made when a function is invoked, and what it references is determined entirely by the call-site where the function is called.

There are 4 rules to follow if you want to figure out what this is referring to

  1. Called with new? Use the newly constructed object.

  2. Called with call or apply (or bind)? Use the specified object.

  3. Called with a context object owning the call? Use that context object.

  4. Default: undefined in strict mode, global object otherwise.

Here, this refers to the global object, that's why this.x is undefined. If you want to enforce it, you can use bind.

In case you want to learn more about all the technicalities you should read this

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Swann
  • 2,413
  • 2
  • 20
  • 28
0

As I can see the above function is a Self-executing function or IIFE (Immediately Invoked Function expressions). These blocks are not methods, meaning these blocks are not called as properties of an Object, thus executing in the context of global scope.

And thus this in your expression will refer to the context of global scope, which does not have a variable x defined, therefore, consoling this.x will return undefined.

I found an awesome blog explaining this on the internet, hope this will help you understand it better. https://www.bennadel.com/blog/2264-changing-the-execution-context-of-your-self-executing-function-blocks-in-javascript.htm

Kumar Aman
  • 271
  • 2
  • 7