Prerequisite:
— Understand JavaScript’s “this” With Ease, and Master It.
— JavaScript Objects
— Understand JavaScript Closures
(This is an intermediate to advanced topic)
Duration: About 40 minutes.
Functions are objects in JavaScript, as you should know by now, if you have read any of the prerequisite articles. And as objects, functions have methods, including the powerful Apply, Call, and Bind methods. On the one hand, Apply and Call are nearly identical and are frequently used in JavaScript for borrowing methods and for setting the this value explicitly. We also use Apply for variable-arity functions; you will learn more about this in a bit.
On the other hand, we use Bind for setting the this value in methods and for currying functions.
Table of Contents
- 1 JavaScript’s Bind Method
- 2 JavaScript’s Bind Allows Us to Set the this Value on Methods
- 3 Bind () Allows us to Borrow Methods
- 4 JavaScript’s Bind Allows Us to Curry a Function
- 5 JavaScript’s Apply and Call Methods
- 6 Set the this value with Apply or Call
- 7 Borrowing Functions with Apply and Call (A Must Know)
- 8 Use Apply () to Execute Variable-Arity Functions
JavaScript’s Bind Method
We use the Bind () method primarily to call a function with the this value set explicitly. It other words, bind () allows us to easily set which specific object will be bound to this when a function or method is invoked.
This might seem relatively trivial, but often the this value in methods and functions must be set explicitly when you need a specific object bound to the function’s this value.
The need for bind usually occurs when we use the this keyword in a method and we call that method from a receiver object; in such cases, sometimes this is not bound to the object that we expect it to be bound to, resulting in errors in our applications. Don’t worry if you don’t fully comprehend the preceding sentence. It will become clear like teardrop in a moment.
Before we look at the code for this section, we should understand the this keyword in JavaScript. If you don’t already understand this in JavaScript, read my article, Understand JavaScript’s “this” With Clarity, and Master It. If you don’t understand this well, you will have trouble understanding some of the concepts discussed below. In fact, many of the concepts regarding setting the “this” value that I discuss in this article I also discussed in the Understand JavaScript’s “this” article.
JavaScript’s Bind Allows Us to Set the this Value on Methods
When the button below is clicked, the text field is populated with a random name.
<pre><code data-language="javascript">
//
//
var user = {
data :[
{name:”T. Woods”, age:37},
{name:”P. Mickelson”, age:43}
],
clickHandler:function (event) {
var randomNum = ((Math.random () * 2 | 0) + 1) – 1; // random number between 0 and 1
// This line is adding a random person from the data array to the text field
$ ("input").val (this.data[randomNum].name + " " + this.data[randomNum].age);
}
}
// Assign an eventHandler to the button’s click event
$ (“button”).click (user.clickHandler);
When you click the button, you get an error because this in the clickHandler () method is bound to the button HTML element, since that is the object that the clickHandler method is executed on.
This particular problem is quite common in JavaScript, and JavaScript frameworks like Backbone.js and libraries like jQuery automatically do the bindings for us, so that this is always bound to the object we expect it to be bound to.
To fix the problem in the preceding example, we can use the bind method thus:
Instead of this line:
$ ("button").click (user.clickHandler);
We simply have to bind the clickHandler method to the user object like this:
$ ("button").click (user.clickHandler.bind (user));
Consider this other way to fix the this value: You can pass an anonymous callback function to the click () method and jQuery will bind this inside the anonymous function to the button object.
Because ECMAScript 5 introduced the Bind method, it (Bind) is unavailable in IE < 9 and Firefox 3.x.
Include this Bind implementation in your code, if you are targeting older browsers:
<pre><code data-language="javascript">
// Credit to Douglas Crockford for this bind method
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError ("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call (arguments, 1),
fToBind = this,
fNOP = function () {
},
fBound = function () {
return fToBind.apply (this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat (Array.prototype.slice.call (arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP ();
return fBound;
};
}
</code></pre>
Let’s continue with the same example we used above. The this value is also bound to another object if we assign the method (where this is defined) to a variable. This demonstrates:
<pre><code data-language="javascript">
// This data variable is a global variable
var data = [
{name:"Samantha", age:12},
{name:"Alexis", age:14}
]
var user = {
// local data variable
data :[
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],
showData:function (event) {
var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1
console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
}
}
// Assign the showData method of the user object to a variable
var showDataVar = user.showData;
showDataVar (); // Samantha 12 (from the global data array, not from the local data array)
</code></pre>
When we execute the showDataVar () function, the values printed to the console are from the global data array, not the data array in the user object. This happens because showDataVar () is executed as a global function and use of this inside showDataVar () is bound to the global scope, which is the window object in browsers.
Again, we can fix this problem by specifically setting the “this” value with the bind method:
<pre><code data-language="javascript">
// Bind the showData method to the user object
var showDataVar = user.showData.bind (user);
// Now the we get the value from the user object because the this keyword is bound to the user object
showDataVar (); // P. Mickelson 43
</code></pre>
Bind () Allows us to Borrow Methods
In JavaScript, we can pass functions around, return them, borrow them, and the like. And the bind () method makes it super easy to borrow methods.
Here is an example using bind () to borrow a method:
<pre><code data-language="javascript">
// Here we have a cars object that does not have a method to print its data to the console
var cars = {
data:[
{name:"Honda Accord", age:14},
{name:"Tesla Model S", age:2}
]
}
// We can borrow the showData () method from the user object we defined in the last example.
// Here we bind the user.showData method to the cars object we just created.
cars.showData = user.showData.bind (cars);
cars.showData (); // Honda Accord 14
</code></pre>
One problem with this example is that we are adding a new method (showData) on the cars object and we might not want to do that just to borrow a method because the cars object might already have a property or method name showData. We don’t want to overwrite it accidentally. As we will see in our discussion of Apply and Call below, it is best to borrow a method using either the Apply or Call method.
JavaScript’s Bind Allows Us to Curry a Function
Function Currying, also known as partial function application, is the use of a function (that accept one or more arguments) that returns a new function with some of the arguments already set. The function that is returned has access to the stored arguments and variables of the outer function. This sounds way more complex than it actually is, so let’s code.
Let's use the <em>bind ()</em> method for currying. First we have a simple greet () function that accepts 3 parameters:
<pre><code data-language="javascript">
function greet (gender, age, name) {
// if a male, use Mr., else use Ms.
var salutation = gender === "male" ? "Mr. " : "Ms. ";
if (age > 25) {
return "Hello, " + salutation + name + ".";
}
else {
return "Hey, " + name + ".";
}
}
</code></pre>
And we use the bind () method to curry (preset one or more of the parameters) our greet () function. The first argument of the bind () method sets the <em>this</em> value, as we discussed earlier:
<pre><code data-language="javascript">
// So we are passing null because we are not using the "this" keyword in our greet function.
var greetAnAdultMale = greet.bind (null, "male", 45);
greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
var greetAYoungster = greet.bind (null, "", 16);
greetAYoungster ("Alex"); // "Hey, Alex."
greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
</code></pre>
When we use the bind () method for currying, all the parameters of the greet () function, except the last (rightmost) argument, are preset. So it is the rightmost argument that we are changing when we call the new functions that were curried from the greet () function. Again, I discuss currying at length in a separate blog post, and you will see how we can easily create very powerful functions with Currying and Compose, two Functional JavaScript concepts.
So, with the bind () method, we can explicitly set the this value for invoking methods on objects, we can borrow
and copy methods, and assign methods to variable to be executed as functions. And as outlined in the Currying Tip
earlier,
you can use bind for currying.
JavaScript’s Apply and Call Methods
The Apply and Call methods are two of the most often used Function methods in JavaScript, and for good reason: they allow us to borrow functions and set the this value in function invocation. In addition, the apply function in particular allows us to execute a function with an array of parameters, such that each parameter is passed to the function individually when the function executes—great for variadic functions; a variadic function takes varying number of arguments, not a set number of arguments as most functions do.
-
Set the this value with Apply or Call
Just as in the bind () example, we can also set the this value when invoking functions by using the Apply or Call methods. The first parameter in the call and apply methods set the this value to the object that the function is invoked upon.
Here is a very quick, illustrative example for starters before we get into more complex usages of Apply and Call:
// global variable for demonstration var avgScore = "global avgScore"; //global function function avg (arrayOfScores) { // Add all the scores and return the total var sumOfScores = arrayOfScores.reduce (function (prev, cur, index, array) { return prev + cur; }); // The "this" keyword here will be bound to the global object, unless we set the "this" with Call or Apply this.avgScore = sumOfScores / arrayOfScores.length; } var gameController = { scores :[20, 34, 55, 46, 77], avgScore:null } // If we execute the avg function thus, "this" inside the function is bound to the global window object: avg (gameController.scores); // Proof that the avgScore was set on the global window object console.log (window.avgScore); // 46.4 console.log (gameController.avgScore); // null // reset the global avgScore avgScore = "global avgScore"; // To set the "this" value explicitly, so that "this" is bound to the gameController, // We use the call () method: avg.call (gameController, gameController.scores); console.log (window.avgScore); //global avgScore console.log (gameController.avgScore); // 46.4
Note that the first argument to call () sets the this value. In the preceding example, it is set to
the gameController object. The other arguments after the first argument are passed as parameters to the
avg () function.The apply and call methods are almost identical when setting the this value except that you pass the function parameters to apply () as an array, while you have to list the parameters individually to pass them to the call () method. More on this follows. Meanwhile, the apply () method also has another feature that the call () method doesn’t have, as we will soon see.
Use Call or Apply To Set this in Callback Functions
I borrowed this little section from my article, Understand JavaScript Callback Functions and Use Them.// Define an object with some properties and a method // We will later pass the method as a callback function to another function var clientData = { id: 094545, fullName: "Not Set", // setUserName is a method on the clientData object setUserName: function (firstName, lastName) { // this refers to the fullName property in this object this.fullName = firstName + " " + lastName; } }
function getUserInput (firstName, lastName, callback, callbackObj) { // The use of the Apply method below will set the "this" value to callbackObj callback.apply (callbackObj, [firstName, lastName]); }
The Apply method sets the this value to callbackObj. This allows us to execute the callback function with the this value set explicitly, so the parameters passed to the callback function will be set on the clientData object:
// The clientData object will be used by the Apply method to set the "this" value getUserInput ("Barack", "Obama", clientData.setUserName, clientData); // the fullName property on the clientData was correctly set console.log (clientData.fullName); // Barack Obama
The Apply, Call, and Bind methods are all used to set the this value when invoking a method, and they do it in slightly different ways to allow use direct control and versatility in our JavaScript code. The this value in JavaScript is as important as any other part of the language, and we have the 3 aforementioned methods are the essential tools to setting and using this effectively and properly.
-
Borrowing Functions with Apply and Call (A Must Know)
The most common use for the Apply and Call methods in JavaScript is probably to borrow functions. We can borrow functions with the Apply and Call methods just as we did with the bind method, but in a more versatile manner.
Consider these examples:
- Borrowing Array Methods
Arrays come with a number of useful methods for iterating and modifying arrays, but unfortunately, Objects do not have as many native methods. Nonetheless, since an Object can be expressed in a manner similar to an Array (known as an array-like object), and most important, because all of the Array methods are generic (except toString and toLocaleString), we can borrow Array methods and use them on objects that are array-like.An array-like object is an object that has its keys defined as non-negative integers. It is best to specifically add a length property on the object that has the length of the object, since the a length property does not exist on objects it does on Arrays.
I should note (for clarity, especially for new JavaScript developers) that in the following examples, when we call Array.prototype, we are reaching into the Array object and on its prototype (where all its methods are defined for inheritance). And it is from there—the source—that we are borrowing the Array methods. Hence the use of code like Array.prototype.slice—the slice method that is defined on the Array prototype.
Let’s create an array-like object and borrow some array methods to operate on the our array-like object. Keep in mind the array-like object is a real object, it is not an array at all:
// An array-like object: note the non-negative integers used as keys var anArrayLikeObj = {0:"Martin", 1:78, 2:67, 3:["Letta", "Marieta", "Pauline"], length:4 };
Now, if wish to use any of the common Array methods on our object, we can:
// Make a quick copy and save the results in a real array: // First parameter sets the "this" value var newArray = Array.prototype.slice.call (anArrayLikeObj, 0); console.log (newArray); // ["Martin", 78, 67, Array[3]] // Search for "Martin" in the array-like object console.log (Array.prototype.indexOf.call (anArrayLikeObj, "Martin") === -1 ? false : true); // true // Try using an Array method without the call () or apply () console.log (anArrayLikeObj.indexOf ("Martin") === -1 ? false : true); // Error: Object has no method 'indexOf' // Reverse the object: console.log (Array.prototype.reverse.call (anArrayLikeObj)); // {0: Array[3], 1: 67, 2: 78, 3: "Martin", length: 4} // Sweet. We can pop too: console.log (Array.prototype.pop.call (anArrayLikeObj)); console.log (anArrayLikeObj); // {0: Array[3], 1: 67, 2: 78, length: 3} // What about push? console.log (Array.prototype.push.call (anArrayLikeObj, "Jackie")); console.log (anArrayLikeObj); // {0: Array[3], 1: 67, 2: 78, 3: "Jackie", length: 4}
We get all the great benefits of an object and we are still able to use Array methods on our object, when we setup our object as an array-like object and borrow the Array methods. All of this is made possible by the virtue of the call or apply method.
The arguments object that is a property of all JavaScript functions is an array-like object, and for this reason, one of the most popular uses of the call () and apply () methods is to extract the parameters passed into a function from the arguments object.
Here is an example I took from the Ember.js source, with comments I added:
function transitionTo (name) { // Because the arguments object is an array-like object // We can use the slice () Array method on it // The number "1" parameter means: return a copy of the array from index 1 to the end. Or simply: skip the first item var args = Array.prototype.slice.call (arguments, 1); // I added this bit so we can see the args value console.log (args); // I commented out this last line because it is beyond this example //doTransition(this, name, this.updateURL, args); } // Because the slice method copied from index 1 to the end, the first item "contact" was not returned transitionTo ("contact", "Today", "20"); // ["Today", "20"]
The args variable is a real array. It has a copy of all the parameters passed to the transitionTo function.
From this example, we learn that a quick way to get all the arguments (as an array) passed to a function is to do:
// We do not define the function with any parameters, yet we can get all the arguments passed to it function doSomething () { var args = Array.prototype.slice.call (arguments); console.log (args); } doSomething ("Water", "Salt", "Glue"); // ["Water", "Salt", "Glue"]
We will discuss how to use the apply method with the arguments array-like object again for variadic functions. More on this later.
- Borrowing String Methods with Apply and Call
Like the preceding example, we can also use apply () and call () to borrow String methods. Since Strings are immutable, only the non-manipulative arrays work on them, so you cannot use reverse, pop and the like. - Borrow Other Methods and Functions
Since we are borrowing, lets go all in and borrow from our own custom methods and functions, not just from Array and String:var gameController = { scores :[20, 34, 55, 46, 77], avgScore:null, players :[ {name:"Tommy", playerID:987, age:23}, {name:"Pau", playerID:87, age:33} ] } var appController = { scores :[900, 845, 809, 950], avgScore:null, avg :function () { var sumOfScores = this.scores.reduce (function (prev, cur, index, array) { return prev + cur; }); this.avgScore = sumOfScores / this.scores.length; } } // Note that we are using the apply () method, so the 2nd argument has to be an array appController.avg.apply (gameController); console.log (gameController.avgScore); // 46.4 // appController.avgScore is still null; it was not updated, only gameController.avgScore was updated console.log (appController.avgScore); // null
Sure, it is just as easy, even recommended, to borrow our own custom methods and functions. The gameController object borrows the appController object’s avg () method. The “this” value defined in the avg () method will be set to the first parameter—the gameController object.
You might be wondering what will happen if the original definition of the method we are borrowing changes. Will the borrowed (copied) method change as well, or is the copied method a full copy that does not refer back to the original method? Let’s answer these questions with a quick, illustrative example:
appController.maxNum = function () { this.avgScore = Math.max.apply (null, this.scores); } appController.maxNum.apply (gameController, gameController.scores); console.log (gameController.avgScore); // 77
As expected, if we change the original method, the changes are reflected in the borrowed instances of that method. This is expected for good reason: we never made a full copy of the method, we simply borrowed it (referred directly to its current implementation).
- Borrowing Array Methods
-
Use Apply () to Execute Variable-Arity Functions
To wrap up our discussion on the versatility and usefulness of the Apply, Call, and Bind methods, we will discuss a neat, little feature of the Apply method: execute functions with an array of arguments.
We can pass an array with of arguments to a function and, by virtue of using the apply () method, the function will execute the
items in the array as if we called the function like this:
createAccount (arrayOfItems[0], arrayOfItems[1], arrayOfItems[2], arrayOfItems[3]);
This technique is especially used for creating variable-arity, also known as variadic functions.
These are functions that accept any number of arguments instead of a fixed number of arguments. The arity of a function specifies the number of arguments the function was defined to accept.
The Math.max() method is an example of a common variable-arity function in JavaScript:
// We can pass any number of arguments to the Math.max () method
console.log (Math.max (23, 11, 34, 56)); // 56
But what if we have an array of numbers to pass to Math.max? We cannot do this:
var allNumbers = [23, 11, 34, 56];
// We cannot pass an array of numbers to the the Math.max method like this
console.log (Math.max (allNumbers)); // NaN
This is where the apply () method helps us execute variadic functions. Instead of the above, we have to pass the array of numbers using apply () thus:
var allNumbers = [23, 11, 34, 56];
// Using the apply () method, we can pass the array of numbers:
console.log (Math.max.apply (null, allNumbers)); // 56
As we have learned earlier, the fist argument to apply () sets the “this” value, but “this” is not used in the Math.max () method, so we pass null.
Here is an example of our own variadic function to further illustrate the concept of using the apply () method in
this capacity:
var students = ["Peter Alexander", "Michael Woodruff", "Judy Archer", "Malcolm Khan"];
// No specific parameters defined, because ANY number of parameters are accepted
function welcomeStudents () {
var args = Array.prototype.slice.call (arguments);
var lastItem = args.pop ();
console.log ("Welcome " + args.join (", ") + ", and " + lastItem + ".");
}
welcomeStudents.apply (null, students);
// Welcome Peter Alexander, Michael Woodruff, Judy Archer, and Malcolm Khan.
Final Words
The Call, Apply, and Bind methods are indeed workhorses and should be part of your JavaScript repertoire for setting the this value in functions, for creating and executing variadic functions, and for borrowing methods and functions. As a JavaScript developer, you will likely encounter and use these functions time and again. So be sure you understand them well.
Be Good. Imagine. Create.
[sc:mongodb-book]
Pingback: Understand JavaScript’s “this” With Ease, and Master It | JavaScript is Sexy
Pingback: Understand JavaScript’s “this” With Clarity, and Master It | JavaScript is Sexy
Pingback: 16 JavaScript Concepts JavaScript Professionals Must Know Well | JavaScript is Sexy
Pingback: JavaScript’s Apply, Call, and Bind Method...
Pingback: JavaScript’s Apply, Call, and Bind Method...
The bind from douglas crockford example is really hard to understand.
I agree. Crockford is a complex guy. Later (when I have a bit of time), I will expound on his bind method to make it clearer.
Do you recommend JS:The good part? I think it like the book that tech you how to write code like Mr.Douglas Crockford.
That is a good book, but not to use as your first book. It should be your second or third book, after you have already learned the basics and understand JavaScript well.
Hi Richard,
I enjoy your articles. I am 3 months into a bootcamp and learning a lot (but still have so far to go!) Anyway, do you recommend any javascript books? I am half way through, “Javascript, the Good Parts” and certain parts are still a little beyond me right now, you are right; although I will say that reading your articles after reading a chapter or two of the book really help to drive things home…but what’s a good book for me to start with? thank you again for the great articles!
@TJ check out Eloquent JavaScript and YDKJS. Both are free/open-source online.
You are awesome as usual! Thanks for your time!
Thank you for reading the blog, and you are welcome.
I’ve learned a lot since I stumbled on this blog, thank you! Keep sharing.
Great. I am very happy to hear that.
great post thanks richard!
Thank you, Robert.
Ever since i have stumbled upon your blog, i must say that my JS concepts have improved a lot. You have unique ability to simplify things in such a way it is easy to grasp.
Keep up the good work.. May be someday you should author a book 🙂
Sri, you are wonderful. Thanks for the wonderful words of encouragement.
I am actually writing a book—more on it later 😉
How come your articles dont appear in the “Javascript Weekly” news letter? Another well explained JS concept.
The OOP in JavaScript post was published in JavaScript Weekly. That was the only one, so I know what you mean.
I don’t know the criteria for being selected, but you can send the editor a Tweet:
https://twitter.com/JavaScriptDaily
Thanks.
I learn something new every time i visit your blog. Thanks richard 🙂
Thank you, Ritesh, and you are welcome 🙂
Hi Richard,
I really love reading your articles and appreciate your work in here; even simple examples guide n00bies very well. Thank you and wish to see more of them.
I’ve got a question, in your greetAYoungster function you didnt define a second parameter so it should return “Hey, Ms. Alex.” instead of “Hey, Alex.” because “” (empty string) is falsey i guess.
Emre, your suggestion that falsy will be the result from a nonexistent (or empty) parameter is correct. But in the example code, if the person’s age is 25 or younger, the salutation variable is not being used at all, so the returned result will always be without “Mr.” or “Ms.”
Here is a working example on JSbin:
http://jsbin.com/okohut/2/edit
Oops i missed that, my mistake.
Thank you! 🙂
Could you please provide example using Microsoft Visual Basic 6. I think VB6 is more performant and powerful than the Java scripting language
hey this is js blog for web dev not ms vb.
thanks for this blog. When I read “borrow function”, I suddenly realize what Array.prototype.slice(arguments) really do, which confused me a long time. Ye, borrow is the key 🙂
sorry, not Array.prototype.slice(argument), but Array.prototype.slice.apply(argument)
You are very welcome, Yougen. I am glad this article was helpful for you.
Hi Richard,
I find a tricky part when borrow method, I modify the code as following:
var gameController = {
scores: [20, 10, 60, 50]
}
var appController = {
scores: [900, 300, 600, 400],
avgScore: null,
maxNum: function(){
this.avgScore = Math.max.apply(null, this.scores);
}
}
appController.maxNum.apply(gameController, gameController.scores);
console.log(gameController.avgScore);// 60
Since gameController does NOT have avsScore property,
but it still works and get the result 60.
Currying is not the same thing as partial function application.
No, they are not, but many books on functional programming do use the “partial application” for currying, since currying is a type of partial application.
It’s probably closer to correct to say that partial function application is a specialization of currying.
Similar post can be found here
http://simplr.co.in/blog/learning-the-chaining-pattern-with-javascript-constructors/
Hello Richard!
Thank you for illustrating the JS “ABC’s” so clearly. This explanation rounded out my understanding of each respective methods coming from Reginald Braithwaite’s JavaScript Allonge (definitely recommend if you haven’t checked it out already!).
I found a code ‘hiccup’ in one of your examples. As a note, I was working through most of the examples using the REPL available to Node v.10.20 and the Google Chrome Console Version 30.0.1599.101.
Within the section ‘Set the this value with Apply or Call,’ under your first code example, your global function ‘avg’ is missing the ‘return’ keyword before ‘this.avgScore = sumOfScores / arrayOfScores.length; .’ Without the ‘return’ keyword, I had a bunch of ‘undefined’ values pop up.
May you please update the code sample to include ‘return’ for future readers? If the function should work without the ‘return,’ I’d like to know more about why one could leave it out. 🙂
Again, much thanks. Please keep up the great work on your blog!
#!/watertype
HI Watertype,
Thanks for taking the time to share this with the rest of the readers. It is very helpful. I take it you are referring to this function:
To be clear, are you saying I need a return stament where I have this // *************
If so, I can’t have the return statement there, or else the last line will never be reached. I am not sure why the code example had some error with REPL.
What happens if you add the return statement after the line:
this.avgScore = sumOfScores / arrayOfScores.length;
// Put return here
Does that work?
Hello again Richard,
Thanks for the reply!
I realized that my interpretation of the intent of that code example was incorrect. Originally, I thought that the avg function was to immediately return the average value of a given array (if say calling console.log upon it). Looking at it again, the avg function was meant to update the `this` object’s avgScore, and then checking it with console.log().
I realized that the example was meant to show the `.call` method’s usage in different `this` contexts. So on my part, it was actually me with the code hiccup, haha!
In all, it’s clear to me now. Again, thanks!
#!/watertype
You are welcome, and thanks for following up.
Great article! it’s really clear and comprehensive with a few examples you’ve given. I’ve been searching for this kind of article to nail down the bind() method and additionally got 2 other methods;) Cool, thank you Richard!
Your articles are helpful and well explained. Thank you. But could I please ask you to remove any leading spaces from the lines in your code samples? (In future posts; I wouldn’t ask you to edit all the old ones.) Your layout is so narrow that the extra spaces at the beginning of each line make nearly every line of code wrap. It makes it harder to read your code. — Thanks
I am confused about why the apply and call methods might be needed for getting the arguments.
Can’t you do inside a function:
var args = arguments;
Instead of:
var args = Array.prototype.slice.call(arguments);
Hi Richard, love this website! I’d be lost in a sea of confusing and disparate tutorials without it 🙂
Above you mention the following:
“Note that another way to fix the this value is that you can pass an anonymous callback function to the click () method and jQuery will bound this inside the anonymous function to the button object.”
I’m not exactly sure what you mean here. I came up with the following, but wanted to double check that I had conceptualized it right:
$(‘button’).click(function() {
var randomNum = Math.round(Math.random());
alert(user.data[randomNum].name);
})
Thanks again for the incredible site!!!
-r
hi,
Can you please explain following concept: function currying at length in a separate blog post, and you will see how we can easily create very powerful functions with Currying and Compose, two Functional JavaScript concepts.
which blog i should check?? where have you explained??
i’m waiting for that. i learnt javascript because your blogs only thanks a lot. also please explain me for classical inheritance and prototyple inheritance in javascript.
Great blog. I’m very new to all of this, so apologies in advance if I’m just being dense, but I had some questions regarding your example of “borrowing” methods using the .bind() function, i.e.:
var cars = {
data:[
{name:”Honda Accord”, age:14},
{name:”Tesla Model S”, age:2}
]
}
cars.showData = user.showData.bind (cars);
cars.showData (); // Honda Accord 14
You correctly note that this is bad practice, because the cars object might already have a showData method that we would be accidentally overwriting.
However, I’m not sure this counts as “borrowing.” Based on your later GameController example of borrowing, borrowing seems to be about invoking object A’s method within the context of object B, whereas this is declaring new methods in Object B.
Thus, to make the above a correct example of borrowing, shouldn’t it just end with:
user.showData.bind(cars)();
// must add () to the end, because bind() doesn’t auto-invoke, unlike apply().
NOT:
cars.showData = user.showData.bind (cars);
cars.showData ();
In which case, is there even a problem using bind()() to borrow? Granted it can’t take additional arguments like apply/call, so is more limited.
Thanks!
Another thanks for these useful collection of posts.
For “apply” vs “call”, I remember “A” is for “apply” and “array” 🙂
Pingback: Clonando objetos en JavaScript | Bitácora del desarrollador
Pingback: sexy.com | JavaScript is Sexy
Thanks, nice post
Is the code for found correct? I don’t get why it uses “oThis” both when “this” is already defined and “oThis” is not.
Hi,
I am beginner in Javascript, and don’t understand follownig line:
cars.showData = user.showData.bind (cars);
Why did you do : ‘user.showData.bind (cars)’, is needed bind in this situation?
cars.showData method is invoked, not in the global context but in Object ‘cars’ context, so
cars.showData = user.showData; don’t do the work?
I apologise in advance for my weak english.
Thank you for the explanation on borrowing methods. I just tried it in one of my scripts and it works great. It saved me from a tedious workaround. Thanks again!
This explanation is just what I was looking for. There is btw not a single YouTube video which adequately explains this subject (hint hint …).
Pingback: Javascript: call() and apply() – Reserves of brain
Thanks for the great post!
I have a question on your illustration:
=====
appController.maxNum = function () {
this.avgScore = Math.max.apply (null, this.scores);
}
appController.maxNum.apply (gameController, gameController.scores);
console.log (gameController.avgScore); // 77
====
I understand how this example works. What I don’t get is why this is the example to answer the question “what will happen if the original definition of the method we are borrowing changes..” . I was expecting an example where the original method “avg” would be changed after the first time it was borrowed. The illustration above was using a new method, so I’m a little confused about the relevance to the question.
Thanks in advance!
Hi! Wonderful blog post; thank you writing it! I have a question about the example given for currying function with the bind method.
In the function below, the arguments are listed in the order: gender, age, and name. So I assumed when the function was curried and saved to a variable, you would need to list the order of the arguments the same, meaning in var greetAnAdultMale = greet.bind (null, “male”, 45); the arguments would be (“male”, 45, null).
However, that is not the case in the example when greetAnAdultMale(“John Hartlove”) is called with a single parameter, it returns the function as “Hello, Mr. John Hartlove.” Why is this? How does the JS interpreter know that when the function is called, the argument given corresponds to the name parameter and is not overwriting the first argument (gender)?
function greet (gender, age, name) {
// if a male, use Mr., else use Ms.
var salutation = gender === “male” ? “Mr. ” : “Ms. “;
if (age > 25) {
return “Hello, ” + salutation + name + “.”;
}
else {
return “Hey, ” + name + “.”;
}
}
after reading your posts i understood all things in js ,thanks alot.
Pingback: Naked JavaScript | Pearltrees
You are right that the following code creates (or potentially overwrites) a showData method on cars…
cars.showData = user.showData.bind (cars);
cars.showData (); // Honda Accord 14
However, you can easily use bind to borrow the showData method from users without creating it on cars by immediately calling it…
user.showData.bind (cars)();
the last example is not so good because the function could be called without the apply method, like so:
….
var args = Array.prototype.slice.apply (arguments[0]);
…..
welcomeStudents ( students);
I have learn a lot from your posts.Thank you !
Great article. Would be even better if you could explain the fundamental differences between bind, call and apply though.
Superb post
Pingback: Bind, Call, Apply method trong Javascrip. Phần 2 - Call và Apply method - BLOG CYO
This is the best site for javascript learning. Objects behaving like an array – Man! that’s pure genius. Till yesterday, I thought arguments object can access only length property, but not anymore. 🙂
Thanks Richard. I am indulging this newly acquired knowledge.
Cheers
Harish
You are Awesome. Thank You so much for the great articles.
Wouldn’t it be more accurate to pass
undefined
asthisArg
to thebind
method for partial functions instead of passingnull
?Thanks Richard.
Almost all tutorial on apply and call seemed a little difficult to me. But, this article made everything easy for me to understand.
Pingback: JavaScript call vs bind vs apply | vasunagpal
Pingback: Bind, Call and Apply in JavaScript - Technical Blogs : Technical Blogs
((Math.random () * 2 | 0) + 1) – 1; // random number between 0 and 1
I really wanna to know how does it work , what this operator ( | ) refer to ?!
Pingback: Understanding THIS in JavaScript. | Learning to code in spare time.
Pingback: JavaScript’s Apply, Call, and Bind Methods are Essential for JavaScript Professionals | JavaScript is Sexy | Paul de Wouters
what you worte is awesome and I Learn alot~!
thankyou~!
Pingback: Preparing Before Hack Reactor Begins | bash $ cat bitchblog
This was an immensely helpful post for me 😀 Took the time to read it all in one sitting and I’m very glad I did. The examples were really helpful and things were generally just written in a clear, concise way. Thank you so much for the great article 😀
A lot of the concepts covered here relate to things I’ve been reading about/practicing otherwise, and this sort of “completed” some of that knowledge for me. It’s a very cool feeling when that moment happens and you suddenly realize how far you’ve come from where you started.
Can you please update your article and add one missing bit: call’ing ot apply’ing a bound function.
For example:
[code]
function do_something(a, b, callback){
// … do something
callback.apply(null, [a, b]);
}
function callback(a, b){
console.log(‘callback called with:’, a, b);
}
do_something(1, 2, callback);
do_something(1, 2, console.log.bind(console)); // bound callback passed
[/code]
Pingback: Javascript – Bind | anxtech
You are Awesome. Thank You so much for the great articles and time.
Thank you a lot for this explanation.
Appreciate! Thanks, great explanation.
Yes, if you don’t need to slice the arguments (meaning, if you want ALL the arguments, instead of just the 2nd and 3rd argument, for example) you can use the code you posted.
Remember, Array.prototype.slice does this:
// Our good friend the citrus from fruits example
var fruits = [‘Banana’, ‘Orange’, ‘Lemon’, ‘Apple’, ‘Mango’];
var citrus = fruits.slice(1, 3);
// citrus contains [‘Orange’,’Lemon’]
What a great article. I really appreciate it and it helped clear up a lot of issues for me!
Hi,
In one of your examples in the Apply/Call section. Is the below a mistake?
avg.call (gameController, gameController.scores);
For this example, since gameController.scores is an array, should we be using apply instead of call?
Thanks,
Anthony Trinh
Pingback: FrontEnd courses list | webappexpress
Thanks for awesome article.. 🙂 I have one question.
When we borrow methods using call and apply, doesn’t borrowed method added to the object for which we borrowed it?
like in bind, when we borrow method for particular object that method is added in that object.
Pingback: New folder | Pearltrees
Pingback: Yet another Call vs Apply query - javascript
Pingback: javascript - Cannot call method 'render' of undefined - CSS PHP
Nice job!!! thanks!!
Pingback: ES6 Arrow Functions: The New Fat & Concise Syntax in JavaScript
Pingback: ES6 Arrow Functions: The New Fat & Concise Syntax in JavaScript | Codango.Com
Thank you for such a wonderfully simple explanations of js concepts!
I am active js developer with almost 2 years of ex. but I felt that my knowledge is more practical than theoretical one (not so easy to speak about it) kind of. Am preparing for work interview and thought I should sort some things out in my head. Your blog has REALLY helped me to do all that. Thanks a ton Richard!
Thanks Richard for wonderful article. Now, I could feel better with javascript 🙂
I have a doubt on function currying example. Below is my code snippet. Question is in comment. Please help clarify.
$(document).ready(function() {
var showUser = userController.clickHandler.bind(userController);
showUser(0);
// I get error as explained above. This is fine.
// $(‘#btn’).click(userController.clickHandler);
// Doubt: This works fine for me although i did not use bind to set this. 1 passed as argument is index.
// so, why I am not getting same error as above? How come passing 1 as argument is setting this object.
$(‘#btn’).click(userController.clickHandler(1));
});
var userController = {
userData : [
{firstName: “Ajay”, age : “30”},
{firstName: “sonu”, age: “30”}
],
clickHandler : function(index) {
$(‘#id’).val(this.userData[index].firstName + ‘ : ‘ + this.userData[index].age);
}
};
Pingback: call() a standard method on function objects | WILTK
Pingback: Introduction to “this” | WILTK
I always search for sites to recycle my knowledge and I must say that yours is one of the best I found. Really helped me to remember and even learn new stuffs.
Thank you.
I always search for sites to recycle my knowledge and I must say that yours is one of the best I found. Really helped me to remember and even learn new stuffs.
Thank you.
Hi Richard ,
Thanks for wonderful article , I cannot think of learning javascript through any other medium 🙂
I have one doubt in call example given above(illustrating how to set this to point to particular object), we have reset global variable :
// reset the global avgScore
avgScore = “global avgScore”;
// To set the “this” value explicitly, so that “this” is bound to the gameController,
// We use the call () method:
avg.call (gameController, gameController.scores);
console.log (window.avgScore);
console.log (gameController.avgScore); // 46.4
But console.log (window.avgScore); this line still shows 46.4 in fiidle
Can you please explain me why so?
I learnt a lot from your post Richard, thank you very much for being awesome and sharing your knowledge to the world like you do!
Now I can continue learning more about functional programming in Javasript
Pingback: JavaScript advanced Concepts - @Mohan Dere
thanks again for great article but i still not 100% sure i understand when should i use call() and when .apply() ???
So, I was searching for a good source of javascript articles to reach the next level of development as I think I am already a intermediate/advanced javascript programmer, and then I found out your site. I really loved it, dude.
Well explained articles, with a lot of advanced stuff that I really did not understand at all, now I can.
Thanks and keep doing this great job.
“`
appController.maxNum = function () {
this.avgScore = Math.max.apply (null, this.scores);
}
appController.maxNum.apply (gameController, gameController.scores);
console.log (gameController.avgScore); // 77
“`
What’s the benefit of passing `gameController.scores` to `appController.maxNum.apply` given that `maxNum` doesn’t make use of any arguments?
super great articles!
one bit of sheer basic internet advice, though:
(I am seriousely visually impaired, and thus more prone to webpage layout issues, which I think many websites don’t really pay attention to, although the Mozilla documentation clearly stresses this point over and over. These things are not obvious to most people – why should it, after all, if you see normally – but make reading very difficult for me.. and maybe other people too.. so here goes)
my eyes are struggling with the readability of your text, especially in the code examples.
two problems:
They sometimes look like they are ‘selected’, having this unneeded cluttering background color on the letters.
(e.g. the part where you explain ‘Here is an example I took from the Ember.js source, with comments..’ has this unneeded eye-wrecking selection-like letters-background , making the reading far more difficult. I think there is no special functional reason to do so, so I thought I’d mention it.).
Also.. the layout of the code examples is awkward: why do you indent them, just to find long single-line // comments wrapping-around and breaking up the typical scoped indentation? I understand the code examples are probably meant to be copy-pasted to a text editor for further experimentation anyways, but the formatting is quite terrible.
Why indent a complete block of text if there is no reasonable scope in sight that actually makes that necessary, snippet-wise? I don’t understand the functional advantage of that, but certainly recognize the visual problem.
The trouble is: I must follow letter by letter by hand, to be able to read my screen (my eyes have very limited resolution, so to speak… born that way, not fixable), and this unneeded word-wrapping messes up my short-term reading memory severely, if you see what I mean. I have to re-read it about five times to know which letters belong to which subject… arghh 😉
I don’t know how straining this indentation and word-wrapping it is for people that don’t have my visual impairment, but I reckon it would be interesting for them too, to just have fluent text without break-up.
Now I find myself copy-pasting it to an external text editor, just to get the formatting somewhat decent, which is rather time-consuming and unneeded in principle.
Also… If you would get rid of the huge, (IMHO) useless white space on the left and right of the webpage, you would have all the screenspace in the world for the actual articles, and there would be no need to word-wrap your comments, breaking up the readability flow of the source-code. On a normal monitor (widescreen is very common nowadays), you actually only use half of your screen space, which is a shame for the nearly-blind so to speak 😉
It first looked like broken CSS or something, but I checked it on various computers and browsers, and they all have the problem, I think it’s a choice in the layout.
For me, this makes this site almost unreadable, while I would be so glad to be able to read it all . I’ve been chewing on these articles for a few weeks now, since I really want to know their content, but I assure you it’s a challenge, just because of the layout.
… this comment is not to diminish the contents of your work (which I find excellent), but just to point out the layout and styling problems, which seeminly nobody else is mentioning. I have – so to speak – the doubtful honour of mentioning the elephant in the room (a bat-blind elephant as I am, probably 😉
Readability and good use of screenspace is important, I think. These articles would be much better without the visual strain!
keep up the good work!
Dhen
cant reverse below
var obj = {0:11,1:22}
console.log (Array.prototype.reverse.call (obj));
output ==== {0: 11, 1: 22}
Why ??
Pingback: 33 JavaScript Concepts Every Developer Should Know (with tutorials) - The web development company Lzo Media - Senior Backend Developer
Pingback: 33 JavaScript Ideas Each Developer Ought to Know (with tutorials) - Abu Sayed
Pingback: Call, Apply, Bind in Java Script | Frontend Interview Questions | What About Coding
Pingback: What is the use of the JavaScript ‘bind’ method? – Code D3
Pingback: Repositorio de conceptos para desarrolladores de JavaScript
Pingback: 33 js concepts: GitHub File Free Download
Pingback: What is the use of the JavaScript 'bind' method?