4

I find myself using jQuery objects with regular js objects often; I'm trying to figure out how I can utilize .call and .apply more often in my scripts when appropriate. I've been testing code to see how it actually works.

However when I run my code below (which essentially just hides all the divs on the page) in firebug on sites I know have jQuery I get varied results; I'm wondering if it's the version of jQuery or is this code just 'buggy' I am to decipher why .call always works but .apply doesn't thought it would be the other way around based on code below

var myApp = {} // instantiate an empty objct
myApp.hide = function (whatever) {
   that = whatever
   $(that).hide()
}
var Numbers = function (object) {
this.object = object;
}

Numbers.prototype.div = $('div');
var numbers = new Numbers();
numbers.div
myApp.hide.call(numbers, numbers.div)
myApp.hide.apply(numbers, numbers.div)

When I firebug the code above either using .call or .apply I get different result depending upon the site. Every site that has jquery .call will work but for some sites like jQuery.com and twitter both will work using .apply and .call but other sites like New York Times and Netflix only .call works - I'm guessing it's the version of jQuery that's causing the difference but am slightly confused because numbers.div always returns an array of all div elements on the page so I would think that would work all the time. Any explanation is appreciated as I am still grasping the concepts of .call and .apply - I always reference Douglas Crockford's book but truthfully he doesn't go into much detail about .apply and .call

jony89
  • 5,155
  • 3
  • 30
  • 40
James Daly
  • 1,357
  • 16
  • 26

2 Answers2

4

.apply need you to pass the arguments as an array.

SO

myApp.hide.call(numbers, numbers.div)

should be same as

myApp.hide.apply(numbers, [numbers.div])

But, in your myApp.hide function, there is no this, so the first parameter of .call or .apply can be anything else, it doesn't matter.

xdazz
  • 158,678
  • 38
  • 247
  • 274
  • thanks xdazz but why does it work on some sites but not others which confuses me, why does .call work at all if it returns an array - does .call still work with arrays where as .apply only works with arrays what the advantages of using one over the other – James Daly Aug 30 '12 at 05:11
  • 1
    .apply uses an array as the second argument and passes everything in that array as parameters to the function. .call on the other hand passes the second parameter and all parameters after that as parameters to the function. – Kevin B Aug 30 '12 at 05:13
  • @JamesDaly No, just check the signature, `foo.call(obj, param1, param2, ...)` vs `foo.apply(obj, [param1, param2, ...])` – xdazz Aug 30 '12 at 05:15
  • ahh I think I finally get it you can use multiple parameters for .call but for .apply you would just store those parameters as a js array; Didn't realize you would utilize multiple parameters for .call - Thanks again xdazz and Kevin B. Guess I'm still slightly confused why it worked on some sites but not for other I'm sure it has to do with the version of jQuery but I get why .call works now over .apply – James Daly Aug 30 '12 at 05:25
2

The Power of call / apply really lies in what Context you want this to be within the called function. For the first parameter determines what it will be. They are a good example of how in Javascript functions, it doesn't matter when/where a function is invoked, but how. (So in your instance, this would be numbers)

Both .apply() and .call() work regardless, the 2nd parameter for either of them is actually optional.

Like everyone is saying the only real difference between the two of them is whether you want to pass the arguments/parameters as an Array (numerical Array [], not an associative array {}).

.apply(contextYouWant, [oneParam, twoParam, etc]);

Or in the instance of .call(), you pass the parameters individually.

.call(contextYouWant, oneParam, twoParam, etc);

Mark Pieszak - Trilon.io
  • 61,391
  • 14
  • 82
  • 96