fixhunt

eslint eqeqeq

labelled safe
Runs / 2026-10-22T18-13-07-829Z-lrfg-eslint-eqeqeqeslint 9.39.52026-10-22 18:13 UTC8 programs × 2 round(s)16 programs, 16 fired, 0 fixed, 0 findings, 0 rejectedmodel cost $0.0030

Analysis Nemotron 3 Super

Flags uses of loose equality (`==`, `!=`) unless they involve typeof expressions or compare two literals of the same type.

Fix: Replaces `==` with `===` and `!=` with `!==` while preserving whitespace around the operator.

10 hazards
  • Changing `x == y` to `x === y` alters behavior when x and y are different types that coerce loosely (e.g., `0 == "0"` is true but `0 === "0"` is false).
  • Rewriting `obj.prop != undefined` to `obj.prop !== undefined` fails if obj.prop is undefined but accessing obj.prop throws (e.g., obj is null), though both sides already evaluate the property access—this hazard is invalid; instead, consider: Rewriting `a == b` to `a === b` may break code that relies on type coercion for equivalence checks (e.g., numeric string comparison).
  • If the operands include getters with side effects, the fix does not reorder evaluation, so no hazard from evaluation order change.
  • If the operands are function calls, the fix does not alter call order or number of invocations.
  • If the expression contains comments between operands and operator (e.g., `a /* comment */ == b`), the fix preserves comments because it only replaces the operator token.
  • In non-strict mode, the fix does not introduce new syntax errors as `===` and `!==` are valid everywhere `==` and `!=` are.
  • If one operand is `null` and the other is `undefined`, `null == undefined` is true but `null !== undefined` is true, so the fix changes semantics—this is a hazard when nullish values are treated as equivalent.
  • If the operands are objects that define custom `valueOf` or `toString`, loose equality may invoke them, while strict equality does not, changing behavior (e.g., `{ valueOf: () => 0 } == 0` is true but `{ valueOf: () => 0 } === 0` is false).
  • If the code relies on loose equality to treat `-0` and `+0` as equal, the fix preserves this as `===` also treats them as equal—no hazard here.
  • If the operands are NaN, `NaN == NaN` is false and `NaN !== NaN` is true, so the fix changes the result from false to true.

Programs

idresulttitlehazard
r1-p001fired, no fixCustom valueOf/toStringIf the operands are objects that define custom `valueOf` or `toString`, loose equality may invoke them, while strict equality does not, changing behavior.
r1-p002fired, no fixLoose equality with -0 and +0If the code relies on loose equality to treat `-0` and `+0` as equal, the fix preserves this as `===` also treats them as equal—no hazard here.
r1-p003fired, no fixType coercion for numeric stringsRewriting `a == b` to `a === b` may break code that relies on type coercion for equivalence checks (e.g., numeric string comparison).
r1-p004fired, no fixGetters with side effectsIf the operands include getters with side effects, the fix does not reorder evaluation, so no hazard from evaluation order change.
r1-p005fired, no fixFunction call operandsIf the operands are function calls, the fix does not alter call order or number of invocations.
r1-p006fired, no fixNaN comparisonIf the operands are NaN, `NaN == NaN` is false and `NaN !== NaN` is true, so the fix changes the result from false to true.
r1-p007fired, no fixRegular expression object equalityregular expressions: escapes, unicode flag, lastIndex with the g flag
r1-p008fired, no fixVar hoisting and redeclarationvar hoisting and re-declaration inside loops or after use
r2-p001fired, no fixASI and semicolon-less code with leading parenthesisASI and semicolon-less code, leading ( or [ on the next line
r2-p002fired, no fixGetter with side effects in operandsIf the operands include getters with side effects, the fix does not reorder evaluation, so no hazard from evaluation order change.
r2-p003fired, no fixStrict vs sloppy mode semanticsstrict vs sloppy mode semantics
r2-p004fired, no fixFunction declarations inside blocks, switch cases, labeled statementsfunction declarations inside blocks, switch cases, labeled statements
r2-p005fired, no fixVar hoisting and re-declaration inside loops or after usevar hoisting and re-declaration inside loops or after use
r2-p006fired, no fix prediction offLoose equality treating -0 and +0 as equalIf the code relies on loose equality to treat `-0` and `+0` as equal, the fix preserves this as `===` also treats them as equal—no hazard here.
r2-p007fired, no fixComments between operands and operatorIf the expression contains comments between operands and operator (e.g., `a /* comment */ == b`), the fix preserves comments because it only replaces the operator token.
r2-p008fired, no fixThis binding: arrow vs function, methods extracted from objects, call/apply/bindthis binding: arrow vs function, methods extracted from objects, call/apply/bind

Sources

r1-p001 · Custom valueOf/toString
1const obj = { valueOf: () => { console.log('valueOf called'); return 0; } };
2console.log(obj == 0);
3console.log(obj === 0);
valueOf called
true
false
r1-p002 · Loose equality with -0 and +0
1console.log(-0 == +0);
2console.log(-0 === +0);
true
true
r1-p003 · Type coercion for numeric strings
1let a = '5', b = 5;
2if (a == b) {
3 console.log('equal via ==');
4}
5if (a === b) {
6 console.log('equal via ===');
7}
equal via ==
r1-p004 · Getters with side effects
1let count = 0;
2const obj = {
3 get prop() {
4 count++;
5 return 42;
6 }
7};
8console.log(obj.prop == 42);
9console.log(count);
true
1
r1-p005 · Function call operands
1let calls = 0;
2function f() { calls++; return 1; }
3console.log(f() == 1);
4console.log(calls);
true
1
r1-p006 · NaN comparison
1console.log(NaN == NaN);
2console.log(NaN !== NaN);
false
true
r1-p007 · Regular expression object equality
1const re1 = /a/g;
2const re2 = /a/g;
3re1.lastIndex = 1;
4console.log(re1 == re2);
5console.log(re1 === re2);
false
false
r1-p008 · Var hoisting and redeclaration
1for (var i = 0; i < 2; i++) {
2 if (i == 0) {
3 var i = 10;
4 console.log(i);
5 }
6}
7console.log(i);
10
11
r2-p001 · ASI and semicolon-less code with leading parenthesis
1let a = 0
2let b = 0
3(function(){ if (a == b) console.log('equal') })()
4[1,2].forEach(v=>{})
r2-p002 · Getter with side effects in operands
1const obj = { get a() { return console.log('get a'), 1 }, get b() { return console.log('get b'), 2 } }
2if (obj.a == obj.b) console.log('match')
3else console.log('no match')
get a
get b
no match
r2-p003 · Strict vs sloppy mode semantics
1'use strict'
2function f() { return this }
3console.log((f() == undefined) ? 'undef' : 'defined')
4console.log((f() === undefined) ? 'undef' : 'defined')
undef
undef
r2-p004 · Function declarations inside blocks, switch cases, labeled statements
1{ function g() { return 1 }
2if (g() == 1) console.log('one')
3else console.log('not one') }
4switch(0) { case 0: function h(){return 2}; if (h() == 2) console.log('two'); break }
one
two
r2-p005 · Var hoisting and re-declaration inside loops or after use
1for (var i = 0; i < 2; i++) {
2 if (i == 0) console.log('zero')
3 else console.log('non-zero')
4 var i = 99
5}
6console.log('i:', i)
zero
i: 100
r2-p006 · Loose equality treating -0 and +0 as equal
1let x = -0
2let y = +0
3console.log(x == y ? 'equal' : 'not equal')
4console.log(x === y ? 'equal' : 'not equal')
equal
equal
r2-p007 · Comments between operands and operator
1let a = 1
2let b = 1
3if (a /* same value */ == b) console.log('equal')
4else console.log('not equal')
equal
r2-p008 · This binding: arrow vs function, methods extracted from objects, call/apply/bind
1const obj = { value: 42, getValue: function() { return this.value } }
2const fn = obj.getValue
3console.log((fn() == undefined) ? 'undef' : 'defined')
4console.log((fn.call(obj) == 42) ? 'match' : 'no match')
undef
match