1

I'm currently working on some exercises to get a deeper understanding of the 'this' keyword. It does seem to have a lot of use cases so I did read on MDN about 'this'. I'm wondering, what does the 'this' keyword in this exercise refer to? I know that when you use apply (which has a maximum of 2 arguments), your first argument is where you want the this 'keyword to be referenced to' and the second argument is an array to which the 'this' keyword is newly referenced to. where is return fn.apply(this,arguments); being referenced to and what is arguments in the second argument? Is it in the function, the window? Sorry, I'm just really confused and trying to wrap my head around it. This is the line of code that I'm confused about:


function add(a, b) {
  return a + b;
}

function invokeMax(fn, num) {
  var counter = 0;
  return function() {
    counter++;
    if (counter > num) {
      return 'Maxed Out!';
    }
    return fn.apply(this, arguments);
  };
}

Brian Aquino
  • 167
  • 1
  • 1
  • 7
  • `this` is [based on scope](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript). – wahwahwah Apr 09 '19 at 00:01

2 Answers2

2

You can console.log() this in the returned function and find out. Here, you will see it points to the global object (or window in a browser). This code doesn't depend on this being anything in particular. You could rewrite it as:

return fn.apply(null, arguments); 

and get the same result.

this is determined by the way functions are called. The function here returns a function that (presumably) you will just call by itself, so the only calling's context is the window:

function add(a, b) {
  return a + b;
}

function invokeMax(fn, num) {
  var counter = 0;
  return function() {
    counter++;
    if (counter > num) {
      return 'Maxed Out!';
    }
    console.log("this is window?", this === window)
    return fn.apply(this, arguments);
  };
}

let f = invokeMax(add, 2)
console.log(f(5, 6))

Calling the same function in a different context leads to a different value of this:

function add(a, b) {
  return a + b;
}

function invokeMax(fn, num) {
  var counter = 0;
  return function() {
    counter++;
    if (counter > num) {
      return 'Maxed Out!';
    }
    console.log("this: ", this)
    return fn.apply(this, arguments);
  };
}

let someObj = {name: "myObj"}
someObj.f = invokeMax(add, 2) // now this will be someObj
someObj.f()

EDIT based on comment

A basic apply() example. The function will use the object passed to the first parameter of apply() as this in the function:

function print(someArg){
  console.log(this.myName, someArg)
}

print.apply({myName: "Mark"}, ["hello"])  // set this to the passed in object
print.apply({myName: "Teddy"}, ["hello"]) // set this to the passed in object
print("hello")                            // called normally `this` will be the widow which doesn't have a `myName` prop.

// but you can give window that property (but probably shouldn't) 
window.myName = "I'm window"
print("hello") 
Mark
  • 90,562
  • 7
  • 108
  • 148
  • I love your explanation. Thank you very much. Just to make sure I'm understanding this correctly, the fn.apply is allowing for me to accept any function in the global scope as my first argument, correct? – Brian Aquino Apr 09 '19 at 00:07
  • 1
    The fist argument to `apply` will be the value used as `this` inside the function. It's probably easier with a simpler example — see edit for a bare-bones example. – Mark Apr 09 '19 at 00:14
0

In that instance this refers to the current scope, which is the function where this is contained. In JavaScript, functions are also objects that can have properties assigned to them.

andriusain
  • 1,211
  • 10
  • 18