4

So, I have 3 functions as follows:

function a() {
  arguments[0]();
}

function b(fn) {
  fn();
}

function c() {
  console.log(this);
}

Now, consider the outputs:

a(c) // Arguments
b(c) // Window
a(() => {console.log(this}) // Window
b(() => {console.log(this)}) // Window

Why does a(c) output Arguments while it is window (considering non-strict) in all other cases?

apnerve
  • 4,391
  • 4
  • 27
  • 43

1 Answers1

3

In JavaScript this usually refers to the object from which the function was called (unless it's an arrow function). So for example if we do something like this:

var obj = { fun: function() { console.log(this); } }
var obj1 = { fun: obj.fun, otherProperty: 123 }
obj.fun(); // equivalent to obj["fun"]()
obj1.fun(); // equivalent to obj1["fun"]()

We will find out that in the first call this refers to obj and in the second it refers to obj1 even though it's the same function.

Now, the arguments variable is an object which stores all the arguments which were passed to the function. If an argument was a function and you access it through the arguments object, it becomes a "parent" object from which the function was called and it becomes the new this in the function's execution context. You can consider your case to be equal to something like this:

function c() {
  console.log(this);
}
var arguments = { "0" : c }
arguments["0"]() // will log the arguments object

In your second invocation (b(c)) the function passed as an argument is called directly inside the parent function, without accessing it through a proxy object - in that case this will be copied from the parent execution scope, which is window.

In the third and fourth example both functions are defined using the arrow function, which saves the value of this from the context in which they were created and they prevent this value from being changed.

More about arrow functions: Arrow functions

Szab
  • 1,158
  • 7
  • 18