biome correctness/noVueDataObjectDeclaration
labelled safe
Analysis Nemotron 3 Super
Flags Vue component `data` options defined as plain objects instead of functions.
Fix: Replaces `data: { ... }` with `data() { return { ... }; }`, preserving the original object literal exactly as the return value.
12 hazards
- If the object contains getter properties, moving them into a function return may change evaluation timing from definition-time to call-time, altering behavior if getters have side effects.
- If the object uses `this` references (e.g., `{ x: this.y }`), those will now be evaluated in the context of the data function call, which may differ from the original object literal evaluation context if `this` was bound differently.
- If the object literal appears in a larger expression where its evaluation order matters (e.g., passed to another function), extracting it into a delayed return changes when side effects occur.
- If the object contains `console.log` or other side-effecting expressions, delaying their execution until the data function is called could affect logging order or timing-dependent tests.
- If the object is shared or referenced elsewhere (e.g., assigned to a variable before use), the fix breaks that sharing by creating a new object each time the function is called.
- If the object uses class fields or private symbols accessed via `this`, those references may become invalid or refer to the wrong `this` after being moved into a function return.
- If the object literal is part of a destructuring or spread operation in a larger object, isolating it into a data function return may alter how it merges with other properties.
- If the code relies on the object being frozen or sealed at definition time, the returned object from the function may not inherit those properties unless explicitly applied.
- If the object contains computed property names that depend on variables in scope, moving them into a function body does not change their evaluation but may affect readability or debugging.
- If the object is defined in a non-extendable context (e.g., inside `Object.preventExtensions`), the fix does not preserve that constraint on the returned object.
- If the data object is used in a mixin or extended component where the original object reference is expected for identity checks, replacing it with a function return breaks reference equality.
- If the object contains `undefined` or `null` values that are relied upon for type checking, the fix preserves them but delays their availability until the data function is invoked.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | silent prediction off | Order of evaluation duplication | order of evaluation when expressions are merged, duplicated or deleted (side effects run twice or never) |
| r1-p002 | silent prediction off | Side effect delay via console.log | If the object contains `console.log` or other side-effecting expressions, delaying their execution until the data function is called could affect logging order or timing-dependent tests. |
| r1-p003 | silent prediction off | ASI with leading parenthesis | ASI and semicolon-less code, leading ( or [ on the next line |
| r1-p004 | silent prediction off | This binding in extracted method | this binding: arrow vs function, methods extracted from objects, call/apply/bind |
| r1-p005 | silent prediction off | Getter side effect | getters, setters and Object.defineProperty side effects |
| r1-p006 | silent prediction off | Var hoisting conflict | var hoisting and re-declaration inside loops or after use |
| r1-p007 | silent prediction off | This reference in data | If the object uses `this` references (e.g., `{ x: this.y }`), those will now be evaluated in the context of the data function call, which may differ from the original object literal evaluation context |
| r1-p008 | silent prediction off | Function declaration in block | function declarations inside blocks, switch cases, labeled statements |
| r2-p001 | silent prediction off | null/undefined distinction | Testing null vs undefined handling in data object - reveals difference between direct object property assignment and function-returned object creation. |
| r2-p002 | silent prediction off | Evaluation order side effects | Side effects in object literal evaluate immediately when defined, but delayed when wrapped in function - changes timing of console.log calls relative to other code. |
| r2-p003 | silent prediction off | Sparse arrays and holes | Array literals with holes behave differently when accessed directly vs through function return - sparse array preservation vs dense conversion. |
| r2-p004 | invalid | Reference identity in mixins | When data object is reused across components/mixins, direct object sharing vs function returning new instances breaks identity checks used for optimization or state tracking. |
| r2-p005 | silent prediction off | Getter evaluation timing | Getters in data object evaluate at definition time when object is literal, but at call time when returned from function - changes when side effects occur relative to component lifecycle. |
| r2-p006 | silent prediction off | Object spread interaction | When data object is part of spread operation, extracting it to function return changes timing of property merge - later properties may overwrite earlier ones depending on evaluation order. |
| r2-p007 | silent prediction off | Frozen object semantics | Direct object literal can be frozen at definition time, but function-returned object is not frozen unless explicitly frozen - breaks assumptions about immutability. |
| r2-p008 | invalid | Control flow interaction | Labels and break statements in object literal initialization interact poorly with early returns - breaking expected control flow when object creation is delayed. |
Sources
r1-p001 · Order of evaluation duplication
1let i = 0;
2const inc = () => ++i;
3export default {
4 data: {
5 a: inc(),
6 b: inc()
7 }
8};
r1-p002 · Side effect delay via console.log
1export default {
2 data: {
3 logged: console.log('first'),
4 value: 42
5 }
6};
first
r1-p003 · ASI with leading parenthesis
1const obj = {}
2export default {
3 data: { x: 1 }
4}(function() { return obj; })()
r1-p004 · This binding in extracted method
1const base = { y: 2 };
2export default {
3 data: {
4 x: this.y + 1
5 },
6 mounted() {
7 console.log(this.data.x);
8 }
9}.call(base);
r1-p005 · Getter side effect
1let count = 0;
2export default {
3 data: {
4 get value() {
5 count++;
6 return count;
7 }
8 }
9};
r1-p006 · Var hoisting conflict
1for (let i = 0; i < 1; i++) {
2 var x = 10;
3}
4export default {
5 data: {
6 y: x
7 }
8};
r1-p007 · This reference in data
1const ctx = { y: 5 };
2export default {
3 data: {
4 x: this.y * 2
5 },
6 created() {
7 console.log(this.data.x);
8 }
9}.call(ctx);
r1-p008 · Function declaration in block
1if (true) {
2 function helper() { return 1; }
3}
4export default {
5 data: {
6 val: helper()
7 }
8};
r2-p001 · null/undefined distinction
1const obj = {};
2export default {
3 data: {
4 a: obj.b,
5 b: () => ({}).c
6 }
7};
r2-p002 · Evaluation order side effects
1let log = [];
2log.push(1);
3export default {
4 data: {
5 x: (log.push(2), 1),
6 y: (log.push(3), 2)
7 }
8};
9log.push(4);
10console.log(log.join(','));
1,2,3,4
r2-p003 · Sparse arrays and holes
1export default {
2 data: {
3 arr: [, 1, , 3]
4 }
5};
6const vm = {};
7vm.data = { arr: [, 1, , 3] };
8console.log(Object.keys(vm.data.arr).length);
9console.log(vm.data.arr.length);
2 4
r2-p004 · Reference identity in mixins (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T20-46-1)
1const shared = { count: 0 };
2export default {
3 data: shared
4};
5export default {
6 data: shared
7};
8console.log(shared === { count: 0 });
r2-p005 · Getter evaluation timing
1let called = 0;
2export default {
3 data: {
4 get value() {
5 called++;
6 return called;
7 }
8 }
9};
10const vm = {};
11vm.data = { get value() { called++; return called; } };
12console.log(vm.data.value);
13console.log(vm.data.value);
1 2
r2-p006 · Object spread interaction
1const base = { a: 1 };
2export default {
3 ...base,
4 data: { b: 2 }
5};
6const base2 = { a: 1 };
7const obj = { ...base2, data: { b: 2 } };
8console.log(obj.a);
9console.log(obj.data.b);
1 2
r2-p007 · Frozen object semantics
1export default {
2 data: Object.freeze({ x: 1 })
3};
4const frozen = Object.freeze({ x: 1 });
5const vm = {};
6vm.data = frozen;
7try {
8 vm.data.x = 2;
9} catch (e) {
10 console.log(e.name);
11}
12console.log(vm.data.x);
TypeError 1
r2-p008 · Control flow interaction (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T20-46-1)
1outer:
2for (let i = 0; i < 1; i++) {
3 export default {
4 data: {
5 x: (() => { break outer; return 1; })(),
6 y: 2
7 }
8 };
9}
10console.log('escaped');