__proto__ and JSON

# Felix Böhm (7 years ago)

After reading that proto is becoming standardized, I was wondering what the impacts on JSON would be. JSON is a subset of ECMAScript, so proto would break current semantics. Even worse, try to run JSON.parse('{"proto": 1}'). The result in Chrome is an empty object. It doesn't inherit from Number.prototype, the proto property simply gets ignored. In terms of portability, that's really bad.

The only solution I can think of would be the {prop = value} syntax, so that proto can only be set via {proto = obj}. Considering that this syntax is intended to trigger setters, it would make a lot of sense.

I know that existing code will break, even some of my own scripts use proto with the old syntax. But I knew that proto is proprietary, and I didn't expect it to work forever.

Otherwise, the JSON spec needs to be changed. I doubt that Doug Crockford would support that.

# David Bruant (7 years ago)

Additionally to JSON, I'd like to ask about if decisions have been made for proto in object literal notation.

David

Le 30/05/2012 14:07, Felix Böhm a écrit :

# Brendan Eich (7 years ago)

David Bruant wrote:

Additionally to JSON, I'd like to ask about if decisions have been made for proto in object literal notation.

That's part of the de-facto proto standard, AFAIK.

David

Le 30/05/2012 14:07, Felix Böhm a écrit :

After reading that proto is becoming standardized, I was wondering what the impacts on JSON would be. JSON is a subset of ECMAScript,

No, not formally. timelessrepo.com/json-isnt-a-javascript-subset (nit-picky but it's on target.)

so proto would break current semantics.

How so? JSON is JSON and it won't change. The subset relation is a good myth. It doesn't bind JSON or JS in reality, since proto is out there and so is JSON.

# Felix Böhm (7 years ago)

2012/5/30 Brendan Eich <brendan at mozilla.com>

David Bruant wrote:

Additionally to JSON, I'd like to ask about if decisions have been made for proto in object literal notation.

That's part of the de-facto proto standard, AFAIK.

David

Le 30/05/2012 14:07, Felix Böhm a écrit :

After reading that proto is becoming standardized, I was wondering what the impacts on JSON would be. JSON is a subset of ECMAScript,

No, not formally. timelessrepo.com/json-**isnt-a-javascript-subsettimelessrepo.com/json-isnt-a-javascript-subset(nit-picky but it's on target.)

so proto would break current semantics.

How so? JSON is JSON and it won't change. The subset relation is a good myth. It doesn't bind JSON or JS in reality, since proto is out there and so is JSON.

/be

Okay, fair point. But JSON.parse should do what it's name says: Parse JSON. Ignoring keys is not an option.

Having proto as a setter would make much more sense for me, too. No magic involved, just some functionality I don't need to care about.

# Brendan Eich (7 years ago)

Felix Böhm wrote:

Okay, fair point. But JSON.parse should do what it's name says: Parse JSON. Ignoring keys is not an option.

JSON.parse must not treat proto specially, per ES5. What's the problem you see?

Having proto as a setter would make much more sense for me, too. No magic involved, just some functionality I don't need to care about.

Please see the thread on "Re: Subclassing built-in constructors", also the meeting notes followups from me. proto has a hidden setter, it masquerades as a data property to avoid leaking a set-[[Prototype]] capability that would require extra checking and could (based on long and hard experience) lead to mischief.

The de-facto and soon to be de-jure Object.prototype.proto standard has no bearing on ES5's JSON.parse, which continues unchanged per the JSON RFC (I trust -- tell me if you see a bug).

# Felix Böhm (7 years ago)

2012/5/30 Brendan Eich <brendan at mozilla.com>

Felix Böhm wrote:

Okay, fair point. But JSON.parse should do what it's name says: Parse JSON. Ignoring keys is not an option.

JSON.parse must not treat proto specially, per ES5. What's the problem you see?

As written before, V8 ignores keys named proto in JSON.parse (I haven't tested other engines yet). I was concerned that this behavior would become the default.

# Mark S. Miller (7 years ago)

On Wed, May 30, 2012 at 7:12 AM, Felix Böhm <esdiscuss at feedic.com> wrote:

2012/5/30 Brendan Eich <brendan at mozilla.com>

Felix Böhm wrote:

Okay, fair point. But JSON.parse should do what it's name says: Parse JSON. Ignoring keys is not an option.

JSON.parse must not treat proto specially, per ES5. What's the problem you see?

As written before, V8 ignores keys named proto in JSON.parse (I haven't tested other engines yet). I was concerned that this behavior would become the default.

These are filed and accepted bugs in v8:

code.google.com/p/v8/issues/detail?id=621, code.google.com/p/v8/issues/detail?id=1310

and tested by test262:

hg.ecmascript.org/tests/test262/file/c84161250e66/test/suite/ch15/15.12/15.12.2/S15.12.2_A1.js

# Mark S. Miller (7 years ago)
# gaz Heyes (7 years ago)

On 30 May 2012 14:52, Brendan Eich <brendan at mozilla.com> wrote:

Felix Böhm wrote:

Okay, fair point. But JSON.parse should do what it's name says: Parse JSON. Ignoring keys is not an option.

JSON.parse must not treat proto specially, per ES5. What's the problem you see?

proto can remove all methods for an object, this could cause a whole block of code to fail when using a property from the JSON object. For example using valueOf/toString with any property that has a null proto.

x={y:{proto:null}}; x=x.y+''; // I'm gonna bail because I have no toString

# Allen Wirfs-Brock (7 years ago)

On May 31, 2012, at 1:37 AM, gaz Heyes wrote:

On 30 May 2012 14:52, Brendan Eich <brendan at mozilla.com> wrote: Felix Böhm wrote: Okay, fair point. But JSON.parse should do what it's name says: Parse JSON. Ignoring keys is not an option. JSON.parse must not treat proto specially, per ES5. What's the problem you see?

proto can remove all methods for an object, this could cause a whole block of code to fail when using a property from the JSON object. For example using valueOf/toString with any property that has a null proto.

x={y:{proto:null}}; x=x.y+''; // I'm gonna bail because I have no toString

Yes, but:

x=JSON.parse{"{y:{proto:null}}"} console.log(x.y+''); //outputs the string "null"

JSON.parse is specified as to not trigger any magic proto behavior when building its object tree. In the above case it simply defines a own property named "proto" whose value is null.