fixhunt

eslint object-shorthand

labelled safe
Runs / 2026-10-22T18-23-22-524Z-h9aw-eslint-object-shorthandeslint 9.39.52026-10-22 18:23 UTC8 programs × 2 round(s)16 programs, 14 fired, 14 fixed, 0 findings, 0 rejectedmodel cost $0.0035

Analysis Nemotron 3 Super

Flags non-shorthand object literal properties/methods where a shorter equivalent exists.

Fix: Replaces longhand property assignments with shorthand when key and variable name match ({x: x} → {x}), and replaces function expressions with method shorthand when the key is a simple identifier or computed expression matching a variable/function name ({m: function(){}} → {m()}, {[n]: function(){}} → {[n]()}).

12 hazards
  • Rewriting {a: a} to {a} changes behavior if 'a' is not in scope, causing ReferenceError.
  • Rewriting {b: function(){}} to {b()} alters the function's name property from 'b' to empty string, breaking reliance on func.name.
  • Rewriting [c]: function(){} to [c](){} may fail if 'c' evaluates to a non-string/symbol key (e.g., number), though unlikely due to rule constraints.
  • If the function expression contains 'use strict' directive, rewriting to method syntax may change strictness scope if surrounding context differs.
  • Comments attached to the function expression (e.g., {b: /* comment */ function(){}}) are lost in the fix as they are not preserved.
  • Rewriting getters/setters like {get x(){}} to shorthand is invalid syntax and never attempted by the fix, but if misapplied would break.
  • If the object literal is used in a context relying on property order (e.g., for...in), the fix preserves order so no hazard, but reordering elsewhere could.
  • In sloppy mode, if the property creates an implicit global via assignment, shorthand does not change this behavior, so no hazard.
  • If the variable 'a' in {a: a} is declared with var and used before declaration, both forms reference the same hoisted variable, so no behavioral change.
  • If the function expression is a generator (*), rewriting to *x(){} preserves generator nature, so no hazard.
  • If the key is an escaped identifier (e.g., {\u0061: a}), the fix may produce invalid syntax if not handled correctly, though ESLint avoids this.
  • If the object literal is nested within a with statement, property resolution changes could theoretically occur, but this is extremely rare and not specific to the fix.

Programs

idresulttitlehazard
r1-p001fix okthis binding: arrow vs functionRewriting function shorthand changes `this` binding; extracting method as const loses original `this` context.
r1-p002fix okstrict vs sloppy mode semanticsIn strict mode, `this` in function shorthand is undefined when called standalone; in sloppy mode it coerces to global, changing outcome after extraction.
r1-p003fix ok prediction offimplicit global in sloppy modeAssignment to undeclared variable creates global in sloppy mode; shorthand rewrite doesn’t affect this since RHS reference unchanged.
r1-p004fix okproperty order reliancefor...in iteration order matters; rule preserves definition order, but if manually reordered post-fix, behavior diverges.
r1-p005fix ok prediction offcomputed key with non-string/symbol[c]: function(){} rewritten to [c]{} fails if c evaluates to number (coerced to string key), though rule avoids non-simple keys.
r1-p006fix okgenerator function preservationGenerator function shorthand rewrite {g: function*(){}} → {g*()} preserves generator nature; next() yields correctly.
r1-p007silentgetter/setter invalid shorthandRule never attempts to rewrite getters/setters; misapplication would break syntax, but here we show they remain intact.
r1-p008fix oknull/undefined distinctionOptional chaining on rewritten shorthand method preserves nullish short-circuit behavior identically to longhand.
r2-p001fix okReferenceError due to out-of-scope variableRewriting {a: a} to {a} changes behavior if 'a' is not in scope, causing ReferenceError.
r2-p002fix okVar hoisting and redeclaration inside loopvar hoisting and re-declaration inside loops or after use
r2-p003fix okName collision across scopes after shadowingname collisions across scopes after a move (shadowing)
r2-p004fix ok prediction offVar used before declaration - no behavioral changeIf the variable 'a' in {a: a} is declared with var and used before declaration, both forms reference the same hoisted variable, so no behavioral change.
r2-p005silent prediction offClass fields and private names interactionclass fields, static blocks, private names, super calls
r2-p006fix okAsync/await ordering and generator yield positionasync/await ordering, generators and yield position
r2-p007fix okNull/undefined distinction with optional chainingnull/undefined distinction, optional chaining short-circuit, nullish vs falsy
r2-p008fix okArguments object, function.length, default parametersarguments object, function.length, default parameters, rest parameters

Sources

r1-p001 · this binding: arrow vs function
1const obj = {
2 m: function() { return this.val; }
3};
4obj.val = 42;
5console.log(obj.m());
6const fn = obj.m;
7try { console.log(fn()); } catch (e) { console.log(e.name + ': ' + e.message); }
--- orig.js	2026-10-22 14:23:31.295384620 -0400
+++ fixed.js	2026-10-22 14:23:34.529525338 -0400
@@ -1,5 +1,5 @@
 const obj = {
-  m: function() { return this.val; }
+  m() { return this.val; }
 };
 obj.val = 42;
 console.log(obj.m());
42
undefined
r1-p002 · strict vs sloppy mode semantics
1"use strict";
2const obj = {
3 m: function() { return this === undefined ? 'strict' : typeof this; }
4};
5obj.val = 1;
6console.log(obj.m());
7const fn = obj.m;
8console.log(fn());
--- orig.js	2026-10-22 14:23:31.296384664 -0400
+++ fixed.js	2026-10-22 14:23:34.519524903 -0400
@@ -1,6 +1,6 @@
 "use strict";
 const obj = {
-  m: function() { return this === undefined ? 'strict' : typeof this; }
+  m() { return this === undefined ? 'strict' : typeof this; }
 };
 obj.val = 1;
 console.log(obj.m());
object
strict
r1-p003 · implicit global in sloppy mode
1"use sloppy";
2(function() {
3 const obj = { p: p };
4 try { console.log(p); } catch (e) { console.log(e.name); }
5})();
--- orig.js	2026-10-22 14:23:31.296384664 -0400
+++ fixed.js	2026-10-22 14:23:34.558526601 -0400
@@ -1,5 +1,5 @@
 "use sloppy";
 (function() {
-  const obj = { p: p };
+  const obj = { p };
   try { console.log(p); } catch (e) { console.log(e.name); }
 })();
r1-p004 · property order reliance
1const obj = { a: a, b: b };
2let a = 1, b = 2;
3let s = '';
4for (const k in obj) s += k + obj[k];
5console.log(s);
--- orig.js	2026-10-22 14:23:31.297384707 -0400
+++ fixed.js	2026-10-22 14:23:34.506524337 -0400
@@ -1,4 +1,4 @@
-const obj = { a: a, b: b };
+const obj = { a, b };
 let a = 1, b = 2;
 let s = '';
 for (const k in obj) s += k + obj[k];
r1-p005 · computed key with non-string/symbol
1const c = 42;
2const obj = { [c]: function() { return 'num'; } };
3console.log(obj['42'](), Object.keys(obj)[0]);
--- orig.js	2026-10-22 14:23:31.298384751 -0400
+++ fixed.js	2026-10-22 14:23:34.510524512 -0400
@@ -1,3 +1,3 @@
 const c = 42;
-const obj = { [c]: function() { return 'num'; } };
+const obj = { [c]() { return 'num'; } };
 console.log(obj['42'](), Object.keys(obj)[0]);
num 42
r1-p006 · generator function preservation
1const obj = {
2 g: function*() {
3 yield 1;
4 yield 2;
5 }
6};
7const it = obj.g();
8console.log(it.next().value, it.next().value, it.next().done);
--- orig.js	2026-10-22 14:23:31.298384751 -0400
+++ fixed.js	2026-10-22 14:23:34.502524163 -0400
@@ -1,5 +1,5 @@
 const obj = {
-  g: function*() {
+  *g() {
     yield 1;
     yield 2;
   }
1 2 true
r1-p007 · getter/setter invalid shorthand
1const obj = {
2 get x() { return this._x || 0; },
3 set x(v) { this._x = v; }
4};
5obj.x = 5;
6console.log(obj.x);
5
r1-p008 · null/undefined distinction
1let obj = null;
2console.log(obj?.m?.());
3obj = { m: function() { return 'hit'; } };
4console.log(obj?.m?.());
5obj = { m: undefined };
6console.log(obj?.m?.());
--- orig.js	2026-10-22 14:23:35.559570181 -0400
+++ fixed.js	2026-10-22 14:23:37.625660161 -0400
@@ -1,6 +1,6 @@
 let obj = null;
 console.log(obj?.m?.());
-obj = { m: function() { return 'hit'; } };
+obj = { m() { return 'hit'; } };
 console.log(obj?.m?.());
 obj = { m: undefined };
 console.log(obj?.m?.());
undefined
hit
undefined
r2-p001 · ReferenceError due to out-of-scope variable
1function f() {
2 try {
3 return {a: a}; // triggers rule
4 } catch (e) {
5 return e.name + ': ' + e.message;
6 }
7}
8console.log(f());
--- orig.js	2026-10-22 14:23:45.208990820 -0400
+++ fixed.js	2026-10-22 14:23:47.863106694 -0400
@@ -1,6 +1,6 @@
 function f() {
   try {
-    return {a: a}; // triggers rule
+    return {a}; // triggers rule
   } catch (e) {
     return e.name + ': ' + e.message;
   }
ReferenceError: a is not defined
r2-p002 · Var hoisting and redeclaration inside loop
1let result = '';
2for (let i = 0; i < 2; i++) {
3 var x = i;
4 let obj = {x: x}; // triggers rule
5 result += obj.x;
6}
7console.log(result);
8// After first iteration: x=0, obj={x:0} -> result='0'
9// After second: x=1 (same var), obj={x:1} -> result='01'
--- orig.js	2026-10-22 14:23:45.209990864 -0400
+++ fixed.js	2026-10-22 14:23:48.965154829 -0400
@@ -1,7 +1,7 @@
 let result = '';
 for (let i = 0; i < 2; i++) {
   var x = i;
-  let obj = {x: x}; // triggers rule
+  let obj = {x}; // triggers rule
   result += obj.x;
 }
 console.log(result);
01
r2-p003 · Name collision across scopes after shadowing
1let a = 1;
2{
3 let a = 2;
4 let o = {a: a}; // triggers rule, inner a=2
5 console.log(o.a); // prints 2
6}
7console.log(a); // prints 1 (outer)
--- orig.js	2026-10-22 14:23:45.210990907 -0400
+++ fixed.js	2026-10-22 14:23:48.979155440 -0400
@@ -1,7 +1,7 @@
 let a = 1;
 {
   let a = 2;
-  let o = {a: a}; // triggers rule, inner a=2
+  let o = {a}; // triggers rule, inner a=2
   console.log(o.a); // prints 2
 }
 console.log(a); // prints 1 (outer)
2
1
r2-p004 · Var used before declaration - no behavioral change
1console.log(typeof a); // 'undefined'
2var a = 5;
3let o = {a: a}; // rule would trigger but no semantic change
4console.log(o.a); // 5
--- orig.js	2026-10-22 14:23:45.211990951 -0400
+++ fixed.js	2026-10-22 14:23:47.345084073 -0400
@@ -1,4 +1,4 @@
 console.log(typeof a); // 'undefined'
 var a = 5;
-let o = {a: a}; // rule would trigger but no semantic change
+let o = {a}; // rule would trigger but no semantic change
 console.log(o.a); // 5
undefined
5
r2-p005 · Class fields and private names interaction
1class Base {
2 constructor() {
3 this.pub = 1;
4 }
5}
6class Derived extends Base {
7 #priv = 2;
8 static staticVal = 3;
9 get obj() {
10 return {
11 pub: this.pub, // triggers rule
12 priv: this.#priv,
13 static: Derived.staticVal
14 };
15 }
16}
17const d = new Derived();
18console.log(d.obj.pub, d.obj.priv, d.obj.static);
1 2 3
r2-p006 · Async/await ordering and generator yield position
1async function* gen() {
2 yield 1;
3 let x = await Promise.resolve(2);
4 yield {x: x}; // triggers rule
5 yield 3;
6}
7gen().next().value.then(v1 => {
8 gen().next().value.then(v2 => {
9 console.log(v1.value, v2.value); // 1, {x:2}
10 });
11});
--- orig.js	2026-10-22 14:23:45.212990995 -0400
+++ fixed.js	2026-10-22 14:23:48.994156096 -0400
@@ -1,7 +1,7 @@
 async function* gen() {
   yield 1;
   let x = await Promise.resolve(2);
-  yield {x: x}; // triggers rule
+  yield {x}; // triggers rule
   yield 3;
 }
 gen().next().value.then(v1 => {
r2-p007 · Null/undefined distinction with optional chaining
1let obj = null;
2let a = undefined;
3try {
4 console.log({a: a}.a?.()); // triggers rule, prints undefined
5} catch (e) {
6 console.log(e.name);
7}
8try {
9 console.log({a: a}.a()); // would throw if not guarded
10} catch (e) {
11 console.log(e.name);
12}
--- orig.js	2026-10-22 14:23:47.763102327 -0400
+++ fixed.js	2026-10-22 14:23:51.535267137 -0400
@@ -1,12 +1,12 @@
 let obj = null;
 let a = undefined;
 try {
-  console.log({a: a}.a?.()); // triggers rule, prints undefined
+  console.log({a}.a?.()); // triggers rule, prints undefined
 } catch (e) {
   console.log(e.name);
 }
 try {
-  console.log({a: a}.a());   // would throw if not guarded
+  console.log({a}.a());   // would throw if not guarded
 } catch (e) {
   console.log(e.name);
 }
undefined
TypeError
r2-p008 · Arguments object, function.length, default parameters
1function f(a, b = 1) {
2 let o = {a: a}; // triggers rule
3 console.log(o.a === arguments[0], f.length);
4 return o;
5}
6f(5); // logs: true 1
--- orig.js	2026-10-22 14:23:48.987155790 -0400
+++ fixed.js	2026-10-22 14:23:51.578269017 -0400
@@ -1,5 +1,5 @@
 function f(a, b = 1) {
-  let o = {a: a}; // triggers rule
+  let o = {a}; // triggers rule
   console.log(o.a === arguments[0], f.length);
   return o;
 }
true 1