The most confusing functions in JavaScript are the call()
and apply()
methods. Interviewers have learned of this and are starting to use it against the unsuspecting candidates. Well, fear no more, by the time you are done reading this page you will know exactly how they work and you will tell that interviewer how it is. :B
First of all both these methods are available on the Function
object. What they do is simple. They call the function. So if you define a function you can call it using any of the two methods.
function myFunction() {
alert("You called?");
}
// the traditional way of calling it will be:
myFunction(); // an annoying pop up with the text "You called?"
// But you can call it with apply
myFunction.apply(); // same alert box
// or call it with ... call
myFunction.call(); // same alert box
You might be wondering, why in the world should you use these methods then if you can just call the function directly. Well, what makes these methods special is the arguments they take. The first argument, is the context in which we want to call the function. Let's explain the context.
Calling a function in a different context
When you call a function using the syntax myFunction()
, the keyword this
refers to the actual window object.
function myFunction() {
alert(this);
}
myFunction(); // will alert "[object Window]"
Using the call or apply method allows you to change this reference to point to something else. One common place you will see this being use is with jQuery. When you select an element and use the click method, inside the function, this
refers to the currently selected element. Ex:
$('#myBigButton').click(function(){
alert(this.id); // will print the id of the element : "myBigButton"
});
In this case this is the actual DOM element. Inside jQuery you will see apply being used for that:
callback.apply( obj, args ); // obj being the element and args being an array of internal jQuery objects like the event object
The call method
Syntax: myFunc.call(context, arg1, arg2,arg3, ...);
This method takes an infinite (hopefully not) number of argument. The first argument being what the this
variable will refer to, and the following arguments will be the arguments of your original function.
myFunc.call(context,"Hello","world",2014);
On the function definition, this means we have 3 arguments. Ex:
function myFunc(string1,string2,year){
alert(string1 + " " + string2 + " " + year);
}
myFunc.call(context,"Hello","world",2014);
// Alert box with message: "Hello world 2014";
The apply method
Syntax: myFunc.call(context, [arg1, arg2,arg3, ...]);
This method only takes 2 argument. The first one being the context, and the second one an array. Each element of the array will be used as an argument for the function. As you can see this method can be more flexible if you have a dynamic number of arguments.
myFunc.call(context,["Hello","world",2014]);
On the function definition, this means we have 3 arguments. Ex:
function myFunc(string1,string2,year){
alert(string1 + " " + string2 + " " + year);
}
myFunc.call(context,"Foo","bar",1999);
// Alert box with message: "Foo bar 1999";
How to use it
You can see that both methods are only different in the number of argument they take. One place I constantly use them is for looping through arrays. I am sure a future versions of JavaScript will implement the .forEach()
method on arrays but in the meanwhile I use my own.
The traditional way to loop through an array is by using a ... for loop. I like the idea of looping through an array by simply using a function. So lets say we want to implement it like this:
var myArray = ["cat","dog","popsicle","bug","random","huh?"];
myArray.loop(function(index) {
alert(this+ " is located at index "+index);
});
Cool syntax right? this
refers to the current value being iterated through the array, and the first argument of our function is the index. Not natively possible but we can implement it. We can add a prototype function called loop
to the array object and loop through the array and call our function on each element. Let's code!
Array.prototype.loop = function (fn){ // our function is the argument
var length = this.length;
for (var i=0;i<length;i++){
var item = this[i]; // item will refer to the current element
fn.apply(item,[i]); // apply takes item as the context variable, and i as the argument for the index
}
};
Now we can run our previous code with ease. This is just one small example of using the call and apply method.
So to recap, the call and apply methods are used to call a function with the ability to change its context. Their main difference is on the number of arguments they take. Call's first argument is the context then the optional infinite number of arguments to pass to the function. Apply's first argument is also a context and the second is an array that will use each element as a function argument.
I hope you now have a good grasp of what each of the functions do. For better understanding, try to use them in your code. And better yet, send me some of your examples. Happy coding.
Sign up for the Newsletter.
Comments
There are no comments added yet.
Let's hear your thoughts