From the ai augmented javascript sample test
Why does AI sometimes generate arrow functions where `this` binding matters?
The item shows a candidate an AI-generated class definition
where the assistant has replaced a method declaration with an
arrow-function class field, breaking the inheritance contract
that the surrounding subclass relies on. The candidate is
asked to identify why the arrow conversion is wrong here, and
when arrow functions for class methods are correct. The
question probes a recurring category of AI-generated mistake:
arrow functions look modern and AI assistants over-prefer
them, but they have a different this-binding semantics that
matters in specific class and event-handler contexts.
What this question tests
The concept under test is the difference between traditional
function expressions, method shorthand, and arrow functions
with respect to this binding, and how AI assistants
sometimes pick the wrong shape for a given context. The
ECMAScript specification defines arrow functions as not having
their own this binding — they capture the lexical this
from the enclosing scope. Method shorthand inside a class or
object literal does have its own this, bound by the call
site. AI-generated code conflates the two when the prompt is
“refactor to arrow functions” or “modernize this class,” and
the result is sometimes a subtle inheritance bug.
The question targets candidates who understand that
“modernization” is not always a behavior-preserving
refactor. An arrow function as a class field is a common
ergonomic choice for event handlers (because the arrow
captures this from the constructor and survives being
passed to addEventListener), but it changes the prototype
shape: the field lives on the instance, not the prototype, so
subclasses that try to call super.method() find no method
to call. Reviewing AI-generated class code for this anti-pattern
is part of the senior-level review loop.
Why this is the right answer
The correct answer distinguishes the cases where each shape
is appropriate. Arrow functions as instance fields are right
for event handlers and callbacks where this capture matters
and inheritance does not:
// Arrow as class field: right for event handlers
class TodoList extends Component {
handleClick = (event) => {
// `this` is the TodoList instance regardless of caller
this.setState({ clicked: true });
};
render() {
return <button onClick={this.handleClick}>Add</button>;
}
}
Method shorthand is right for methods that are part of a
class’s public API and may be overridden or called via
super:
// Method shorthand: right for the class API
class TodoList {
add(item) {
this.items.push(item);
}
}
class PriorityTodoList extends TodoList {
add(item) {
if (item.priority === 'high') this.items.unshift(item);
else super.add(item); // works because `add` is on the prototype
}
}
The AI-generated bug is converting add to an arrow class
field. The conversion looks identical to a casual reader, but
super.add() from the subclass throws TypeError: super.add is not a function because the field on the parent instance is
shadowed by the field on the child instance, and neither lives
on the prototype where super looks.
A smaller version of the same bug shows up when AI assistants
convert the body of forEach or map callbacks into arrow
functions inside a method that uses function:
// Correct: arrow captures `this` from the surrounding method
class Cart {
total() {
return this.items.reduce((sum, item) => sum + this.tax(item.price), 0);
}
}
// Buggy: function expression has its own `this` (undefined in strict mode)
class Cart {
total() {
return this.items.reduce(function (sum, item) {
return sum + this.tax(item.price); // TypeError: this is undefined
}, 0);
}
}
In this second case the arrow is correct and the function expression is wrong. The senior-level skill is applying the right shape per context, not picking one shape for all cases.
What the wrong answers reveal
The plausible wrong options each map onto a different
misconception about this:
- “Arrow functions are always safer, so the AI is right.”
This conflates the two cases above. Arrow functions are
safer for callbacks where
thiscapture matters; they are wrong for class methods that participate in inheritance. Picking this option suggests the candidate has not internalized the prototype-vs-instance distinction. - “Add
bind(this)in the constructor.” This is a pre-class-fields workaround that adds noise and doesn’t solve the inheritance problem. Binding a method in the constructor still puts the method on the instance, sosuper.method()from a subclass still fails. Picking this option suggests the candidate learned a 2015-era pattern and hasn’t updated. - “Use a regular function and call it via
Function.call.” This is technically possible but gratuitous. The language-level fix is to use method shorthand for methods and arrow class fields for handlers. Reaching for.callto fix an AI-generated bug is a code smell.
How the sample test scores you
In the AIEH 5-question AI-Augmented JavaScript sample, this item contributes one of five datapoints aggregated into a single ai_js_proficiency score via the W3.2 normalize-by-count threshold. Binary scoring per item: 5 for the correct option, 1 for any of the three wrong options. With 5 binary items, the average ranges 1–5 and the level threshold maps avg ≤ 2 to low, ≤ 4 to mid, > 4 to high.
Data Notice: Sample-test results are directional indicators only. A 5-question sample can’t reliably distinguish between “understands
thisbinding deeply” and “got lucky on these specific items”; for a verified Skills Passport credential, take the full 50-question assessment.
The full assessment probes class semantics, prototypes,
event-handler ergonomics, strict mode, and the specific
gotchas (bind chains, new.target, super in static
methods) at depth. See the scoring methodology for
how AI-Augmented JavaScript scores map onto the AIEH 300–850
Skills Passport scale.
Related concepts
- Class fields proposal and timing. Arrow class fields shipped in stable Node.js and major browsers around 2022; AI training data from before that period sometimes generates pre-fields workarounds (constructor binding, decorator patterns) that are no longer needed. Reviewers should upgrade these when they appear.
- React
useCallbackand stable references. In function components, the equivalent of “method on instance vs method on prototype” is “callback wrapped inuseCallbackvs inline arrow.” AI-generated React code sometimes uses inline arrows in JSX where stable references matter for child memoization; the review skill transfers. bindand partial application.Function.prototype.bindremains useful for partial application (binding leading arguments) and for explicit-this contexts; the AI-augmented reviewer’s job is recognizing whenbindis the right tool and when it is cargo-culted.
For the broader AI-Augmented JavaScript lineup including the full 50-question assessment, see the tests catalog and javascript fundamentals prep for related study materials. Hiring teams should explore the assess page for ready-to-deploy skill assessments.
Sources
- Ecma International. (2024). ECMAScript 2024 Language
Specification (ECMA-262, 15th edition). — Section 15.3
defines arrow function expressions; Section 13.3.6 covers
method definitions and
super. https://tc39.es/ecma262/ - MDN Contributors. (2024). Arrow function expressions — JavaScript Reference. Mozilla Developer Network. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
- MDN Contributors. (2024). Public class fields — JavaScript Reference. Mozilla Developer Network. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields
- TC39. (2021). Class Fields proposal (Stage 4). https://github.com/tc39/proposal-class-fields