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 regular function expression (including async and generator variants) whose body never references this, or

  • <functionLiteral> is an arrow function. Arrow functions inherit this lexically from the surrounding scope, so bind cannot 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

  • bind allocates a new exotic function object, sets up its [[BoundThis]] and [[BoundTargetFunction]] slots, and is consistently slower than calling the original function directly. When this is 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);

© 2026 Xygeni. All rights reserved