Well, to answer your first question: Why do we put null
there?
To understand why you have to first understand what this
, .call
, and .apply
mean in general. Long story short, this
is a reference to the execution context of a series of lines of code (function, method or global scope). Normally, the default value of this
is the global context Window
(in the browser) or Object [global]
(in NodeJS):
But the execution context run inside a method that belongs to an object is the instance of that object prototype:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
return this.name + ' ' + this.age;
}
const me = new Person('Luis', 28);
me.sayHello();
//> "Luis 28"
Person.prototype.sayHello.apply({
name: 'Someone Else',
age: 100
});
//> "Someone Else 100"
// No array of arguments since
// sayHello() doesn't have params.
The execution context explanation by itself can fit inside a book chapter but since we’re working with objects here it’s ok to be concise. You can observe how the meaning of this
was changed by apply
. Same would have happened if I used me.sayHello.apply
, me.sayHello.bind
or Person.prototype.sayHello.bind
since bind
also changes the meaning of this
and the added arguments are sent to the function it’s being bounded to a new context.
Then why sometimes we add null
instead? Because sometimes a method doesn’t rely on this
to yield a result. That’s exactly the case of Math.max
; it works by comparing the arguments
array-like object rather than this
so we don’t actually need to set the context; but since the context is the first argument we can’t skip it so it’s common to put null
or this
.
Now, the second question: No, bind doesn’t only accept the new this
context, it also accepts arguments separately which will be sent to the bound function. For example:
f.bind(newContext, arg1, arg2, arg3)();
// is now equal to
f(arg1, arg2, arg3); // with the new context of this
null
is the first argument sent to .apply
being called on Math.max
and the resulting function will receive the second argument which is the array of parameters.