Skip to content
Astera Technology

Why did an imported member change an object’s prototype?

Construct own data properties so source member names remain data.

Download complete case notes and answer keys ↓

Read the source and its declared rule

The original input is a parsed plain JSON object with an own __proto__ member. Object.assign into a normal empty object follows its target setter behaviour and can replace that target’s prototype. The corrected local construction uses Object.fromEntries to create own data properties.

Filled synthetic input
RecordInput JSON
Base input{"raw":"{\"__proto__\":{\"mark\":\"changed\"},\"label\":\"A\"}"}
Download editable CSV ↓

Compare the actual paths

The bad target loses the own member and inherits mark changed. Good output has own keys __proto__ and label, with no inherited mark. This fixture changes only its fresh local target.

Misleading and corrected outputs
PathOutput JSON
Misleading path{"ownKeys":["label"],"prototypeMark":"changed","ownData":[["label","A"]]}
Corrected path{"ownKeys":["__proto__","label"],"prototypeMark":null,"ownData":[["__proto__",{"mark":"changed"}],["label","A"]]}
Download editable CSV ↓
Local Node.js program: 22.23.3 or 24.14.1
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};

import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
    const parsed=JSON.parse(i.raw);const object=corrected?Object.fromEntries(Object.entries(parsed)):Object.assign({},parsed);
    return {ownKeys:Object.keys(object),prototypeMark:Object.getPrototypeOf(object).mark??null,ownData:Object.entries(object)};
  };
const cases=[{"label":"misleading base","input":{"raw":"{\"__proto__\":{\"mark\":\"changed\"},\"label\":\"A\"}"},"expected":{"ownKeys":["label"],"prototypeMark":"changed","ownData":[["label","A"]]},"corrected":false},{"label":"corrected base","input":{"raw":"{\"__proto__\":{\"mark\":\"changed\"},\"label\":\"A\"}"},"expected":{"ownKeys":["__proto__","label"],"prototypeMark":null,"ownData":[["__proto__",{"mark":"changed"}],["label","A"]]},"corrected":true},{"label":"constructor remains own data","input":{"raw":"{\"constructor\":\"C\"}"},"expected":{"ownKeys":["constructor"],"prototypeMark":null,"ownData":[["constructor","C"]]},"corrected":true},{"label":"text proto member remains data","input":{"raw":"{\"__proto__\":\"P\"}"},"expected":{"ownKeys":["__proto__"],"prototypeMark":null,"ownData":[["__proto__","P"]]},"corrected":true}];
for(const test of cases){
  const actual=run(test.input,test.corrected);
  assert.deepEqual(actual,test.expected,test.label);
  console.log(test.label,actual);
}
Download runnable example ↓

Check boundaries before the next load

constructor and a text-valued __proto__ remain ordinary own data in the corrected path.

Editable boundary records and expected outputs
CaseInput JSONExpected output JSON
Own constructor member{"raw":"{\"constructor\":\"C\"}"}{"ownKeys":["constructor"],"prototypeMark":null,"ownData":[["constructor","C"]]}
Text-valued proto member{"raw":"{\"__proto__\":\"P\"}"}{"ownKeys":["__proto__"],"prototypeMark":null,"ownData":[["__proto__","P"]]}
Download editable CSV ↓

Should __proto__ disappear from accepted source data?

Show the worked answer

No. The chosen contract preserves it as an own member without allowing it to replace the object prototype.

Related resources