fixhunt

eslint no-extra-bind

labelled safe
Runs / 2026-10-22T18-16-14-875Z-t5t1-eslint-no-extra-bindeslint 9.39.52026-10-22 18:16 UTC8 programs × 2 round(s)16 programs, 4 fired, 4 fixed, 0 findings, 3 rejectedmodel cost $0.0029

Analysis Nemotron 3 Super

Flags unnecessary .bind() calls where the function does not reference 'this' and no arguments are pre-bound.

Fix: Removes the trailing .bind(callExpr) when the function body contains no 'this' references and no arguments are bound beyond the thisArg.

8 hazards
  • Removing .bind() changes the function's identity, breaking equality checks (e.g., ===) against the original bound function.
  • If the bound function is used as a constructor, removing .bind() alters instance creation behavior since bound functions cannot be constructors.
  • The rewrite may expose the function to accidental 'this' binding from surrounding context if used as a method.
  • If the function relies on lexical scoping via bind() to capture outer variables (unrelated to this), removal breaks closure semantics—though rare, this is possible if bind() was misused for closure-like behavior.
  • Comments attached to the .bind() call (e.g., // ignore this) are discarded during autofix, potentially removing developer intent.
  • In strict mode, removing .bind() may alter 'this' value from undefined to the global object if the function is called indirectly.
  • If the bound function is passed to higher-order functions that depend on its specific length or name (e.g., for debugging), removal may break those dependencies.
  • When bind() is chained (e.g., .bind().bind()), removing only the outer bind() may leave an inner unnecessary bind(), requiring multiple passes; the autofix does not handle nested cases.

Programs

idresulttitlehazard
r1-p001silent prediction offComments attached to .bind() are lost1. Comments attached to the .bind() call are discarded during autofix
r1-p002silent prediction offClass field captures broken bind2. Class fields, static blocks, private names, super calls
r1-p003silent prediction offMethod context hijack after fix3. Rewrite exposes function to accidental this binding from surrounding context
r1-p004silent prediction offArguments object and length exposed4. Arguments object, function.length, default parameters, rest parameters
r1-p005fix okVar hoisting interferes with rebind5. Var hoisting and re-declaration inside loops or after use
r1-p006silent prediction offCoercion via + vs template literal6. Numeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt
r1-p007silent prediction offGetter side effect broken by fix7. Getters, setters and Object.defineProperty side effects
r1-p008invalidASI hazard with leading paren8. ASI and semicolon-less code, leading ( or [ on the next line
r2-p001invalidControl Flow Hazard: break/continue/finallylabel/break/continue control flow, finally blocks, early returns in nested blocks
r2-p002silent prediction offStrict Mode Indirect Call 'this' ShiftIn strict mode, removing .bind() may alter 'this' value from undefined to the global object if the function is called indirectly.
r2-p003fix okBind Comment Discarded During AutofixComments attached to the .bind() call (e.g., // ignore this) are discarded during autofix, potentially removing developer intent.
r2-p004silentASI Hazard: Leading Paren After Semicolon-less LineASI and semicolon-less code, leading ( or [ on the next line
r2-p005silent prediction offConstructor Use: Bound Function Cannot ConstructIf the bound function is used as a constructor, removing .bind() alters instance creation behavior since bound functions cannot be constructors.
r2-p006invalidRegExp lastIndex and Unicode Flag Interactionregular expressions: escapes, unicode flag, lastIndex with the g flag
r2-p007fix okClass Fields and Private Names Capture Broken by Fixclass fields, static blocks, private names, super calls
r2-p008fix okOrder of Evaluation: Side Effects Duplicated or Lostorder of evaluation when expressions are merged, duplicated or deleted (side effects run twice or never)

Sources

r1-p001 · Comments attached to .bind() are lost
1let f = function () {
2 console.log(this === undefined ? 'strict' : this);
3}.bind(null) /* preserve this comment */;
4f();
<ref *1> Object [global] {
  global: [Circular *1],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  queueMicrotask: [Function: queueMicrotask],
  structuredClone: [Function: structuredClone],
  atob: [Getter/Setter],
  btoa: [Getter/Setter],
  performance: [Getter/Setter],
  fetch: [Function: fetch],
  crypto: [Getter]
}
r1-p002 · Class field captures broken bind
1class C {
2 prop = function () {
3 return this.x;
4 }.bind({x: 1});
5}
6const c = new C();
7console.log(c.prop());
1
r1-p003 · Method context hijack after fix
1const obj = {
2 m: function () {
3 return this.value;
4 }.bind({value: 42})
5};
6console.log(obj.m());
7console.log(obj.m.call({value: 99}));
42
42
r1-p004 · Arguments object and length exposed
1const f = function (a, b = 1, ...rest) {
2 console.log(arguments.length, this === undefined ? 'und' : 'def', f.length);
3}.bind(null, 10);
4f(20, 30);
3 def 0
r1-p005 · Var hoisting interferes with rebind
1for (var i = 0; i < 2; i++) {
2 var g = function () {
3 return i;
4 }.bind(null);
5}
6console.log(g());
--- orig.js	2026-10-22 14:16:22.999714841 -0400
+++ fixed.js	2026-10-22 14:16:25.267785352 -0400
@@ -1,6 +1,6 @@
 for (var i = 0; i < 2; i++) {
   var g = function () {
     return i;
-  }.bind(null);
+  };
 }
 console.log(g());
2
r1-p006 · Coercion via + vs template literal
1const obj = {
2 toString() { return 'obj'; },
3 valueOf() { return 42; }
4};
5const s = function () {
6 return this;
7}.bind(obj);
8console.log(s() + '');
9console.log(`${s()}`);
42
obj
r1-p007 · Getter side effect broken by fix
1const obj = {};
2Object.defineProperty(obj, 'prop', {
3 get() {
4 this.accessed = true;
5 return 42;
6 }
7});
8const p = function () {
9 return this.prop;
10}.bind(obj);
11p();
12console.log(obj.accessed ? 'yes' : 'no');
yes
r1-p008 · ASI hazard with leading paren (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-16-1)
1let x = function () { return 1 },
2(y = function () { return 2 })
3console.log(x(), y())
r2-p001 · Control Flow Hazard: break/continue/finally (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-16-1)
1LOOP: {
2 try {
3 console.log((function () {
4 for (let i = 0; i < 3; i++) {
5 if (i === 1) continue LOOP;
6 if (i === 2) return;
7 }
8 console.log('reached');
9 }).bind(null));
10 throw new Error('unreachable');
11 } catch (e) {
12 console.log(e.message);
13 } finally {
14 console.log('finally executed');
15 }
16}
r2-p002 · Strict Mode Indirect Call 'this' Shift
1"use strict";
2const f = (function () { return typeof this; }).bind(null);
3const g = f;
4console.log(g());
object
r2-p003 · Bind Comment Discarded During Autofix
1const log = (function () {
2 console.log('no this used');
3}).bind(undefined); // preserve comment
4console.log(typeof log);
--- orig.js	2026-10-22 14:16:37.782179809 -0400
+++ fixed.js	2026-10-22 14:16:40.654271608 -0400
@@ -1,4 +1,4 @@
 const log = (function () {
   console.log('no this used');
-}).bind(undefined); // preserve comment
+}); // preserve comment
 console.log(typeof log);
function
r2-p004 · ASI Hazard: Leading Paren After Semicolon-less Line
1let x = 1
2(function () {
3 console.log('called');
4}).bind(null)
5[x] = [x + 1]
6console.log(x)
r2-p005 · Constructor Use: Bound Function Cannot Construct
1function C() { this.value = 'bound'; }
2const BoundC = C.bind({});
3try {
4 new BoundC();
5 console.log('constructed');
6} catch (e) {
7 console.log(e.name + ': ' + e.message);
8}
9console.log(typeof BoundC.prototype)
constructed
undefined
r2-p006 · RegExp lastIndex and Unicode Flag Interaction (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-16-1)
1const regex = /\\u{1f600}/gu;
2const test = (function () {
3 return regex.lastIndex;
4}).bind(null);
5regex.test('😀');
6console.log(test());
r2-p007 · Class Fields and Private Names Capture Broken by Fix
1class Base {
2 #x = 42;
3 getX() { return this.#x; }
4}
5class Derived extends Base {
6 getXBound = (() => this.getX()).bind(this);
7}
8const d = new Derived();
9console.log(d.getXBound());
--- orig.js	2026-10-22 14:16:37.827181243 -0400
+++ fixed.js	2026-10-22 14:16:41.193288886 -0400
@@ -3,7 +3,7 @@
   getX() { return this.#x; }
 }
 class Derived extends Base {
-  getXBound = (() => this.getX()).bind(this);
+  getXBound = (() => this.getX());
 }
 const d = new Derived();
 console.log(d.getXBound());
42
r2-p008 · Order of Evaluation: Side Effects Duplicated or Lost
1let counter = 0;
2const inc = (function () {
3 return ++counter;
4}).bind(null);
5console.log(inc() + inc());
--- orig.js	2026-10-22 14:16:37.830181338 -0400
+++ fixed.js	2026-10-22 14:16:41.892311318 -0400
@@ -1,5 +1,5 @@
 let counter = 0;
 const inc = (function () {
   return ++counter;
-}).bind(null);
+});
 console.log(inc() + inc());
3