Passing `null` as context object vs directly calling the function

From this question, given that I don’t want to specify any context, hence, passing null to thisArg in call().

What would be the difference between line 2 and line 3 in the following code? Is there any benefit from doing one over the other?

function sum(a,b) { return a + b; }
var result1 = sum.call(null,3,4);     // 7
var result2 = sum(3,4);               // 7

Similarly for apply():

var arr = [1,2,4];
var result3 = Math.max.apply(null, arr);   // 4
var result4 = Math.max(...arr);            // 4

>Solution :

It depends on whether the function you’re calling was defined in loose mode or strict mode.

When calling a loose-mode function, the following three things all call the function such that this within the call is the global object for the environment (globalThis, aka window on browsers):

  • Calling the function without setting this: fn()
  • Calling the function providing a this value of undefined: fn.call(undefined) and similar
  • Calling the function providing a this value of null: fn.call(null) and similar

With a strict mode function, the first two both cause this during the call to be undefined, and the third (explicitly setting it to null) sets it to (you guessed it) null.

Examples:

function loose() {
    console.log(`loose: ${this === null ? "null" : typeof this}`);
}

loose();
loose.call(undefined);
loose.call(null);

function strict() {
    "use strict";
    console.log(`strict: ${this === null ? "null" : typeof this}`);
}

strict();
strict.call(undefined);
strict.call(null);

In the normal case, if you don’t need to set this to anything in particular, just call the function so the default behavior takes place.

  • One wrinkle: If you have an array of arguments you need to spread out as discrete arguments to the function, in any even vaguely up-to-date environment, you can use spread notation to do that: fn(...theArray). If you’re stuck in an obsolete environment, the rough equivalent is fn.apply(undefined, theArray).

If you have a specific need to set a specific this value, you can do that via call or apply (as you’ve found), including (for strict mode functions) undefined or null.

Leave a Reply