Skip to content

noUselessCall (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"noUselessCall": "error"
}
}
}
}

Disallow unnecessary .call() and .apply().

.call() and .apply() run a function and let you choose what this refers to inside it: their first argument becomes this. When that is the same value the function would get from a normal call, .call() and .apply() change nothing. foo.call(undefined, a) does the same thing as foo(a), and obj.foo.call(obj, a) does the same thing as obj.foo(a).

Calling the function directly is also faster. .call() and .apply() add an extra step to every call, and .apply() creates an array only to hold the arguments. JavaScript engines, the programs that run your code in browsers and Node.js, can often skip this extra work, but a direct call never has it.

This rule reports .call() and .apply() when their first argument is:

  • the object the function is read from, such as obj in obj.foo.call(obj);
  • null, undefined, or void followed by any value, such as void 0, when the function is not read from an object, such as foo.call(null).

.apply() is only reported when it has exactly two arguments and the second one is written out as an array, like [a, b], because then the items of the array can be passed to the function directly.

This rule looks at how the code is written, not at the values it produces. In a[i++].foo.call(a[i++]), both a[i++] are written the same way, so the call is reported even though they refer to different items.

foo.call(undefined, 1, 2, 3);
code-block.js:1:1 lint/nursery/noUselessCall ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This .call() is unnecessary.

> 1 │ foo.call(undefined, 1, 2, 3);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The function gets the same this value as it would if you called it directly.

ℹ Call the function directly instead.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

foo.apply(null, [1, 2, 3]);
code-block.js:1:1 lint/nursery/noUselessCall ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This .apply() is unnecessary.

> 1 │ foo.apply(null, [1, 2, 3]);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The function gets the same this value as it would if you called it directly.

ℹ Call the function directly and pass the items of the array as arguments instead.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

obj.foo.call(obj, 1, 2, 3);
code-block.js:1:1 lint/nursery/noUselessCall ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This .call() is unnecessary.

> 1 │ obj.foo.call(obj, 1, 2, 3);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The function gets the same this value as it would if you called it directly.

ℹ Call the function directly instead.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

a.b.foo.apply(a.b, [1, 2, 3]);
code-block.js:1:1 lint/nursery/noUselessCall ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ This .apply() is unnecessary.

> 1 │ a.b.foo.apply(a.b, [1, 2, 3]);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ The function gets the same this value as it would if you called it directly.

ℹ Call the function directly and pass the items of the array as arguments instead.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

// The `this` value is different.
foo.call(obj, 1, 2, 3);
foo.apply(obj, [1, 2, 3]);
obj.foo.call(null, 1, 2, 3);
obj.foo.apply(otherObj, [1, 2, 3]);
// The arguments are not written out as an array.
foo.apply(undefined, args);
obj.foo.apply(obj, args);