The apply
and call
methods in every function allow it to provide a custom value for this
.
function print() {
console.log(this.toPrint);
}
print.apply({ toPrint: "Foo" }); // >> "Foo"
print.call({ toPrint: "Foo" }); // >> "Foo"
You might notice that the syntax for both the invocations used above are the same. i.e. The signature looks similar.
But there is a small difference in their usage, since we are dealing with functions and changing their scopes, we still need to maintain the original arguments passed to the function. Both apply
and call
support passing arguments to the target function as follows:
function speak() {
var sentences = Array.prototype.slice.call(arguments);
console.log(this.name+": "+sentences);
}
var person = { name: "Sunny" };
speak.apply(person, ["I", "Code", "Startups"]); // >> "Sunny: I Code Startups"
speak.call(person, "I", "<3", "Javascript"); // >> "Sunny: I <3 Javascript"
Notice that apply
allows you to pass an Array
or the arguments
object (array-like) as the list of arguments, whereas, call
needs you to pass each argument separately.
These two methods give you the freedom to get as fancy as you want, like implementing a poor version of the ECMAScript's native bind
to create a function that will always be called as a method of an object from an original function.
function bind (func, obj) {
return function () {
return func.apply(obj, Array.prototype.slice.call(arguments, 1));
}
}
var obj = { name: "Foo" };
function print() {
console.log(this.name);
}
printObj = bind(print, obj);
printObj();
This will log
"Foo"
The bind
function has a lot going on
obj
will be used as the value of this