7

I've seen it done differently in code out there, but is there any benefit or reason to doing a (blank params) .call / .apply over a regular () function execution.

This of course is an over-simplified example

var func = function () { /* do whatever */ };

func.call();
func.apply();

VERSUS just the simple parenthesis.

func();

Haven't seen any information on this anywhere, I know why call/apply are used when params are passed.

Cœur
  • 32,421
  • 21
  • 173
  • 232
Mark Pieszak - Trilon.io
  • 44,537
  • 13
  • 74
  • 89
  • 3
    @FeistyMango: Definitely not a dupe of that. – Jon Apr 09 '13 at 13:54
  • Where have you seen such code? I thought (and answered) that it was to make sure `this` is empty, but that's not the case. As far as I can tell through some quick experiments, it's a pointless practice. – Pointy Apr 09 '13 at 13:59
  • Sure it is. He is asking the benefit/reasons for call vs apply. Isn't that essentially the same as asking the difference between the two??? – Matthew Cox Apr 09 '13 at 13:59
  • Nope, he's asking the reasons to use `.call` or `.apply` without a `this` argument versus simply calling the function. – Bart Apr 09 '13 at 14:00
  • @FeistyMango I was putting the 2 in the same category, I was looking more at why would someone do a blank param `funcName.call();` versus `funcName();` – Mark Pieszak - Trilon.io Apr 09 '13 at 14:00
  • @FeistyMango read the question - he's asking about using **either** `.call()` **or** `.apply()` with no arguments instead of just calling a function directly – Pointy Apr 09 '13 at 14:00
  • @Pointy I've just seen it randomly here and there, always blew my mind, it must of been someone that didn't understand how to use `.call/apply` correctly. I guess if it keeps the global window object as the normal `()` call does, it's identical then – Mark Pieszak - Trilon.io Apr 09 '13 at 14:02

2 Answers2

6

When you call a method with func();, this variable inside the method points to window object.

Where as when you use call(...)/apply(...) the first parameter passed to the method call becomes this inside the method. If you are not passing any arguments/pass null or undefined then this will become global object in non strict mode.

Arun P Johny
  • 365,836
  • 60
  • 503
  • 504
  • 2
    Nope, `this` will still point to the global object, unless you explicitly pass `undefined` as the first argument. – Bart Apr 09 '13 at 13:57
  • 1
    Bart is correct - in fact `this` will be `window` even when you explicitly pass `null` or `undefined`. In "strict" mode it works, but then just plain `func()` also gets `this` set to `undefined`. – Pointy Apr 09 '13 at 14:00
  • 1
    @Bart yes you are right https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/call – Arun P Johny Apr 09 '13 at 14:00
  • Wow very interesting, definitely good to know! So maybe some of the code I had seen (wish I could find an example right now) was in Strict mode intending it to be undefined, not sure why they'd want that.. – Mark Pieszak - Trilon.io Apr 09 '13 at 14:06
  • Then again, if you're in strict mode, `this` will not reference the global object either if a simple func() call is made. So even in strict mode, I don't see any reason to use `func.call()` without a `this` argument. – Bart Apr 09 '13 at 14:10
0

Yes, there is an important difference in some cases. For example, dealing with callbacks. Let's assume you have a class with constructor that accepts callback parameter and stores it under this.callback. Later, when this callback is invoked via this.callback(), suddenly the foreign code gets the reference to your object via this. It is not always desirable, and it is better/safer to use this.callback.call() in such case.

That way, the foreign code will get undefined as this and won't try to modify your object by accident. And properly written callback won't be affected by this usage of call() anyways, since they would supply the callback defined as an arrow function or as bound function (via .bind()). In both such cases, the callback will have its own, proper this, unaffected by call(), since arrow and bound functions just ignore the value, set by apply()/call().