Unnecessary .bind() On A Function That Does Not Use this
ID |
javascript.no_extra_bind |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
JavaScript |
Tags |
code-smell, efficiency |
Description
Reports calls to Function.prototype.bind() that cannot have any visible effect because the bound function does not depend on this. Specifically, the rule fires on a single-argument call of the form <functionLiteral>.bind(thisArg) when:
-
<functionLiteral>is an inline regularfunctionexpression (includingasyncand generator variants) whose body never referencesthis, or -
<functionLiteral>is an arrow function. Arrow functions inheritthislexically from the surrounding scope, sobindcannot rebind it; the call is always meaningless.
Calls whose receiver is not an inline function literal (obj.method.bind(other)), and partial-application calls that pass extra pre-bound arguments (.bind(this, a, b)), are intentionally out of scope.
Rationale
-
bindallocates a new exotic function object, sets up itsandslots, and is consistently slower than calling the original function directly. Whenthisis never read inside the body the work is wasted. -
The presence of
.bind(…)misleads readers into believing the function depends on its receiver, hiding the fact that it does not. -
For arrow functions the call is doubly misleading: the binding is silently ignored at runtime, which can cause real bugs when a developer assumes the receiver was rebound.
// Bad
const greet = function () { return "hello"; }.bind(this);
const sum = (function (x) { return x + 1; }).bind(null);
const log = (() => console.log("hi")).bind(other);
Remediation
Drop the .bind(…) and use the function expression directly. For arrow functions, just remove the call.
// Good
const greet = function () { return "hello"; };
const sum = function (x) { return x + 1; };
const log = () => console.log("hi");
If the function legitimately uses this, leave the bind in place — the rule will not flag it:
// Kept: function depends on its receiver
const getName = function () { return this.name; }.bind(user);