Ways to call a function
There are 3 ways to execute a function in javascript. Given the following reverse function (this example function returns a reversed string):
var reverse = function(text){
return text.split("").reverse().join("");
};
// Or
function reverse(text){
return text.split("").reverse().join("");
}
We could execute it as :
call property
The call property allow you to execute a function and change the this
context correctly, followed by the specifical parameters separed by a comma as you do usually with a normal function.
var animals = [
{ species: 'Lion', name: 'King' },
{ species: 'Whale', name: 'Fail' }
];
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
}).call(animals[i], i);// Change the this context to the animal object
}
apply property
apply is very similar to call
, except for the type of arguments it supports. You can use an arguments array instead of a named set of parameters. With apply, you can use an array literal or an array variable.
The following example overrides console.log method. However, we want to do the same thing that console.log does but something before and something after, therefore we use apply
to execute the original console.log method so we don't need to worry about the position of the arguments as they'll be sent in the same way they came. Note that the arguments variable is an array (learn more about the keyword arguments inside a function here).
var originalLog = console.log;
console.log = function() {
// Do something your before execute something
AnImaginaryFunctionThatDoesSomething(arguments);
// Call the function as it would have been called normally:
// Note that with apply we change the this context and send
originalLog.apply(this, arguments);
// Run another thing after the original console.log
};
execute directly
Nothing will broke up if execute a function directly if you decide to invoke a function directly. However you can't change the this
context and the parameters will be always limited as the same way call property does.
You only need to check if the variable is a function before being invoked.
if(typeof(reverse) === "function"){
reverse("otto");
}
What is the difference
You didn't get the difference between them with the previous examples?. No problem, the difference between apply and call is really simple. See the following example :
var teacher = function(name, age, area) {
console.log("My name is " + name + ", i'm "+age+" years old and i'm a " + area + " teacher. The context of this is " + this);
};
teacher("John", 20, "History");
teacher.apply(true, ["Patty",23,"Music"]);
teacher.call(undefined, "Bruce", 44 ,"Mathematics");
// Outputs
//My name is John, i'm 20 years old and i'm a History teacher. The context of this is [undefined]
//My name is Patty, i'm 23 years old and i'm a Music teacher. The context of this is [true]
//My name is Bruce, i'm 44 years old and i'm a Mathematics teacher. The context of this is [undefined]
They accomplish the same task, execute a function. The only difference is the way the arguments can be sent and how many arguments can be provided.
- apply, call or invoke directly a function, will simply execute it , with or without arguments.
- The
this
context can be changed only in the apply and call methods. - Invoke directly a function or use call doesn't allow dinamical parameters, therefore they're explicitly declared (if 5 parameters are declared, only 5 will be sent).
- Using apply allow you to send dinamically parameters to the function (ilimited parameters, if the array as second parameter has 500 items, then the function will receive respectively the 500 items of the array as parameters).
Remember that the first and second parameter of apply()
and call()
are optional, not required. Therefore they're just another way to execute a function but with allowed customization. So there's no a recommended way to execute a function, as the one you choose only needs to fit to your needs.