Skip to content

Use the null prototype when parsing YAML maps#678

Open
remcohaszing wants to merge 3 commits intoeemeli:mainfrom
remcohaszing:null-proto
Open

Use the null prototype when parsing YAML maps#678
remcohaszing wants to merge 3 commits intoeemeli:mainfrom
remcohaszing:null-proto

Conversation

@remcohaszing
Copy link
Copy Markdown

YAML maps map a key to a value. These keys may conflict with keys on the JavaScript Object prototype. Several JavaScript APIs that use a plain object to represent a key/value map, use a null prototype.

Closes #675

YAML maps map a key to a value. These keys may conflict with keys on the
JavaScript `Object` prototype. Several JavaScript APIs that use a plain
object to represent a key/value map, use a null prototype.

Closes eemeli#675
@remcohaszing
Copy link
Copy Markdown
Author

I realized JSON.parse() doesn’t use null prototypes, but for example the toml package goes.

Comment thread src/nodes/Pair.ts Outdated
ctx: ToJSContext
): ReturnType<typeof addPairToJSMap> {
const pair = ctx.mapAsMap ? new Map() : {}
const pair = ctx.mapAsMap ? new Map() : { __proto__: null }
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Directly setting __proto__ is deprecated, and not the way we should do this. Please use Object.create(null) instead.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting! TIL!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I see that article states:

The __proto__ property can also be used in an object literal definition to set the object [[Prototype]] on creation, as an alternative to Object.create(). See: object initializer / literal syntax. That syntax is standard and optimized for in implementations, and quite different from Object.prototype.__proto__.

And the linked Object initializer page even uses it in examples.

So I think my initial implementation was good, and slightly more readable.

The use of `__proto__` is deprecated.
Copy link
Copy Markdown
Owner

@eemeli eemeli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a linter failure, otherwise looks good!

@eemeli
Copy link
Copy Markdown
Owner

eemeli commented May 2, 2026

The documentation will also need an update, at least under Document#toJS().

@remcohaszing
Copy link
Copy Markdown
Author

A friend of mine did some benchmarking on null prototypes and figured that objects with a null prototype provide a 3x memory penalty and a significant access penalty vs regular objects, because of V8 optimizations.

So maybe it’s better to not merge this PR altogether.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use a null prototype to represent YAML maps

2 participants