Quick Tip: Calling JavaScript Methods on Other Objects
basixvideos

Quick Tip: Calling JavaScript Methods on Other Objects

Tutorial Details
  • Topic: JavaScript
  • Difficulty: Easy
  • Estimated Completion Time: 15 minutes

You’ll never stop being surprised by JavaScript. In this quick tip, I’m going to show you how to use the JavaScript methods, call and apply, to call your functions of other objects. Don’t know what I mean? Let’s get started!

View Screencast

Press the HD button for a clearer picture.

Subscribe to our YouTube page to watch all of the video tutorials!

Using Call and Apply

Here’s the scenario: we have two objects:

var joe = {
    name : "Joe",
    greet : function (name) {
        alert(this.name + " says hello to " + name);
    }
};

var jill = {
    name : "Jill"
};

It’s pretty simple to get Joe to greet Jill:

joe.greet("Jill");

But how can we get Jill to greet Joe? She doesn’t have a greet method (and let’s assume we can’t / won’t / shouldn’t give her one). Well, because everything in JavaScript—including functions—is an object, everything can have a method, or a function that can be called from it. Functions are given two methods that allow you to call them in different contexts.

The context of a method is basically the object that will be this when the function is called. In our greet method, this refers to the object joe, because that’s what it is a part of.

Now, try this:

joe.greet.call(jill, "Joe");

The call method on JavaScript functions allows you to change the function’s context. The first parameter we pass in will be the new context: in this case, that’s jill. Subsequent parameters are the parameters to the function you’re calling. In this case, “Joe” will be passed to greet. If you run this, you’ll get an alert box with the message “Jill says hi to Joe.”

There’s also an apply method; the only difference is that it takes the parameters of the method as an array, rather than as raw parameters, a la the call method.

joe.greet.call(jill, ["Joe"]);

If you have a hard time remembering whether it’s call or apply that takes the array, remember that apply and array both start with ”a.”

Thanks for reading!

Add Comment

Discussion 21 Comments

  1. Adam says:

    So there is a typo at the end, it should be,
    joe.greet.apply(jill, ["Joe"]);
    NOT
    joe.greet.call(jill, ["Joe"]);

    Thanks for sharing!

  2. esranull says:

    nice post thanks a lot

  3. MrMutation says:

    Nice tutorial Andrew.

    However, I have a small bone to pick.

    In a lot of tutorials, the author is trying to demonstrate one small concept, and they come up with a really contrived example. I can understand this rationale, but I feel it’s wrong. It’s why so many beginners are *still* using document.write…because the tutorial they read used it “just for demonstration purposes”.

    You say “let’s say you can’t/won’t/…”, but we don’t know who’s reading this. They may not understand *exactly why* your example is silly, and who knows how they’ll interpret your qualification. . Some of them are only going to look at the code. Some of them may not speak English well, and can only pick up parts of the tutorial. Some may just not pay attention, or just plain not understand. Even more advanced users may get confused.

    By using an example scenario in which you wouldn’t use apply, you confuse the reader as to when they should actually use it.

    I guarantee someone will read this tutorial who hasn’t learned about OO or inheritance yet, and walks away thinking this is a neat way to save typing and starts writing code where they write an instance method once and “apply” it to everything…because that’s how you (seem) to use it.

    Programming is not just “plumbing”, it’s also largely about conceptual modeling, and I think it’s best to teach that at the same time when possible. All examples should be as if they were plucked from a real program.

    Your example was pretty darn close, but it’s clear that Joe and Jill should each have their own greet method, or really inherit it from their shared prototype. You should use an example problem that is best solved by the technique you wish to demonstrate.

    Your second example is better, but the damage is already done by the first and it’s only in the video.

    In the case of your first example I would tweak it to something like:

    “Let’s say you are writing a game, and creating some objects for the game. First you have a Jill object; for a girl in the game. She has a name (Jill), and can say hello to the player.

    var jill = {
    name: “Jill”,
    greet: function (name) {
    alert(this.name + ” says ‘Hello ” + name + “‘!”);
    }
    }

    So now, somewhere in your game you do:
    jill.greet(“Billy”)
    and get:
    “Jill says ‘Hello Billy’!”

    Let’s say you start building more objects, like a table. It also has a name but it doesn’t have a greet function because tables don’t talk.

    var table = {
    name: “Mom’s nice coffee table”
    }

    However…. let’s say, at one particular point in the game the table comes alive for just a moment and you want it to say hello. You could add a greet method, but that seems a waste for just one moment in the game and the table normally doesn’t talk.”

    …go on to demonstrate apply.

    This is basically the same as your current example, but now it gives more background on exactly when and why you would use apply, and it also plants the seed for things like OO, interfaces, duck-typing, etc.

    This, combined with your second example (and perhaps also mentioning one of the most common uses for these methods: calling Array functions on arguments) would give the reader a pretty good understanding of these methods.

    Sorry to vent here, it’s just something that’s been on my mind and this example sort of set me off.

    • Author

      Thanks for taking the time to explain that, MrMutation. Although I hadn’t given it too much though, I subconsciously though that giving a full, real world example would bombard the watcher / reader with too much code and make it difficult to understand the one simple technique I was trying to get across. I guess that’s wrong: using deeper techniques doesn’t mean I have to explain them. Thanks again; I’ll make sure to remember this next time.

      By the way, you should submit a few quick tips / tutorials; I think you’d do a great job :)

  4. Adam says:

    I knew about apply(), but I never really knew that it could be apply-ied like this. So fast and neat was your example. Much appreciated!

  5. Kevin Jensen says:

    It makes me happy to see a tutorial on apply() and call(). I love apply(). I think my favorite use is mixing the Math object with arrays:

    var arrayOfNumbers = [1,4,60,8,40,37,58,62,693,7,347,54,32,62,11,432,59];
    var biggest = Math.max.apply( null, arrayOfNumbers ); // biggest == 693
    var smallest = Math.min.apply( null, arrayOfNumbers ); // smallest == 1
    // etc.

    Great job, Andrew! FTW!

  6. evanxg says:

    I knew this trick.
    This tip would have been great if it was given in a real world example.
    Anyway which software are using to write and test in Javascript ? is it available for Windows ?

    • Author

      Well, I think my second example was pretty real world; I’ll be using it in an upcoming tutorial :) Another real world use of this is converting the array-like object arguments into a real array:

      var args = Array.prototype.slice.call(arguments);

      For coding, I was using JSBin; it’s a web app.

  7. devs says:

    this from oreilly book – javascript pattern, right???
    haha~

  8. Jaspal Singh says:

    Nice Article on Javascript tricks.
    Thanks for sharing.

  9. Daniel says:

    nice tutorial! I have a question though. When I copied your code from the second example and run it myself I got a range error and checking afterwards showed that the array created using array.prototype.push.apply had a considerably shorter length. What do you thing about that? does apply have a limit?

    And what about .concat(); I coud it be used too?

    • Author

      You can use call and apply on any functions; of course, if the object you’re using it on doesn’t have the required properties (and I’m using properties more generally there), it won’t work.

      Can you put your code in a JSbin and post the link? I’ll see if I can help you find the issue :).

      • Daniel says:

        here’s the code! http://jsbin.com/oqabe4/edit

        Firefox 4 beta 6 runs the code but the resulting array isn’t complete. It only has 523264 items
        Chrome 7 throws the RangeError for i > ~130700 but it doesn’t seem to be consistent…

        regarding concat I ment using it to solve this very problem. Like so: arr2 = [].concat(arr); I’m going to try it right now myself ;)

      • Daniel says:

        tried the concat method and it worked really well, but it wasn’t as fast as your solution. It took about twice as long as with apply in my browser (Firefox 4 beta 6). It was times faster than looping though :D

        looping: 201ms
        applying: 17ms
        concat: 32ms

  10. Vic says:

    You talk about the apply method but in both examples you use call() – Am I wrong thinking that’s an obvious typo?

  11. Falkon says:

    Hi Guys,
    I have an issue that I trying to solve, with spry menu items, and changing content without the refreshing of the main page.
    I have heard Iframes, tried it, and did not work, ( also not so much info on this matter either) even tried adobe….nothing.

    Would you please help me figuring this out? It is to; when a user presses the menu item the content of the page will address the requested URL without the whole page refreshing. ( like flash)

    I would really appreciate all the help.
    Have a great and a blessed weekend everyone.

    Falkon

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.