New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify Symbol.prototype methods as [[Writable]]: false #273

Closed
jdalton opened this Issue Dec 22, 2015 · 9 comments

Comments

Projects
None yet
5 participants
@jdalton
Member

jdalton commented Dec 22, 2015

I'm not sure if this is mentioned in another place in the spec, I didn't see it, but I noticed all implementations have symbol methods like Symbol#toString as [[Writable]]: false.

Object.getOwnPropertyDescriptor(Symbol.prototype, 'toString')
// {writable: true, enumerable: false, configurable: true}

but

var s = Symbol();
s.toString = function() { return ''; };
s.toString(); // => "Symbol()"
@domenic

This comment has been minimized.

Show comment
Hide comment
@domenic

domenic Dec 22, 2015

Member

This is just the usual confusion between wrapper objects and primitives. It's the same as

var s = false;
s.toString = function() { return ''; };
s.toString(); // => "false"

line 2 creates a useless wrapper object that is immediately discarded. It doesn't set {Symbol,Boolean}.prototype.toString.

Member

domenic commented Dec 22, 2015

This is just the usual confusion between wrapper objects and primitives. It's the same as

var s = false;
s.toString = function() { return ''; };
s.toString(); // => "false"

line 2 creates a useless wrapper object that is immediately discarded. It doesn't set {Symbol,Boolean}.prototype.toString.

@jdalton

This comment has been minimized.

Show comment
Hide comment
@jdalton

jdalton Dec 22, 2015

Member

Ah yes, my bad.

var s = Object(Symbol());
typeof s; // => "object"
s.toString = function() { return '' };
s.toString(); // => ""

then

var o = {};
o[s] = 1;
Object.keys(o);
// => []
Object.getOwnPropertySymbols(o)
// => [Symbol()]

Kinda neat it works as an object too.

Member

jdalton commented Dec 22, 2015

Ah yes, my bad.

var s = Object(Symbol());
typeof s; // => "object"
s.toString = function() { return '' };
s.toString(); // => ""

then

var o = {};
o[s] = 1;
Object.keys(o);
// => []
Object.getOwnPropertySymbols(o)
// => [Symbol()]

Kinda neat it works as an object too.

@jdalton jdalton closed this Dec 22, 2015

@claudepache

This comment has been minimized.

Show comment
Hide comment
@claudepache

claudepache Dec 22, 2015

Contributor

line 2 creates a useless wrapper object that is immediately discarded

It's less cumbersome to think as: Primitives are frozen.

Contributor

claudepache commented Dec 22, 2015

line 2 creates a useless wrapper object that is immediately discarded

It's less cumbersome to think as: Primitives are frozen.

@domenic

This comment has been minimized.

Show comment
Hide comment
@domenic

domenic Dec 22, 2015

Member

It's less cumbersome to think as: Primitives are frozen.

Except "modifying" them doesn't throw in strict mode.

Member

domenic commented Dec 22, 2015

It's less cumbersome to think as: Primitives are frozen.

Except "modifying" them doesn't throw in strict mode.

@claudepache

This comment has been minimized.

Show comment
Hide comment
@claudepache

claudepache Dec 22, 2015

Contributor

Except "modifying" them doesn't throw in strict mode.

It should. (It does in JSC and V8. If it doesn’t in ECMA262, I consider it as a bug.)

Contributor

claudepache commented Dec 22, 2015

Except "modifying" them doesn't throw in strict mode.

It should. (It does in JSC and V8. If it doesn’t in ECMA262, I consider it as a bug.)

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Dec 22, 2015

Member

@claudepache

Except "modifying" them doesn't throw in strict mode.

It should. (It does in JSC and V8. If it doesn’t in ECMA262, I consider it as a bug.)

No, Wrapper objects are not created frozen and hence there should be no strict mode errors associated with creating own properties on them. This is legacy behavior for Number, Boolean, String and modify it would be a web breaking change. As a new kind of primitive wrapper, it was conceivable that Symbol wrapper could be frozen. But that would then have created an internal inconsistency between Symbol wrapper objects and the other pre-existing kinds of wrapper objects..

Member

allenwb commented Dec 22, 2015

@claudepache

Except "modifying" them doesn't throw in strict mode.

It should. (It does in JSC and V8. If it doesn’t in ECMA262, I consider it as a bug.)

No, Wrapper objects are not created frozen and hence there should be no strict mode errors associated with creating own properties on them. This is legacy behavior for Number, Boolean, String and modify it would be a web breaking change. As a new kind of primitive wrapper, it was conceivable that Symbol wrapper could be frozen. But that would then have created an internal inconsistency between Symbol wrapper objects and the other pre-existing kinds of wrapper objects..

@anba

This comment has been minimized.

Show comment
Hide comment
@anba

anba Dec 22, 2015

Contributor

there should be no strict mode errors associated with creating own properties on them.

Except in most cases PutValue ends up in 9.1.9 [[Set]], which returns false if the receiver is a primitive value and the property is not present (or a data property). And then a TypeError is thrown. (I think this is what @claudepache meant.)

Contributor

anba commented Dec 22, 2015

there should be no strict mode errors associated with creating own properties on them.

Except in most cases PutValue ends up in 9.1.9 [[Set]], which returns false if the receiver is a primitive value and the property is not present (or a data property). And then a TypeError is thrown. (I think this is what @claudepache meant.)

@claudepache

This comment has been minimized.

Show comment
Hide comment
@claudepache

claudepache Dec 22, 2015

Contributor

I meant that it is more useful that it throws, so that the programmer is warned that their intention could not be satisfied. The wrapper object dance is a legacy specification detail. In practice, what the programmer sees is what @jdalton reported: attempt to define an own property on a primitive fails, just as for frozen objects.

Contributor

claudepache commented Dec 22, 2015

I meant that it is more useful that it throws, so that the programmer is warned that their intention could not be satisfied. The wrapper object dance is a legacy specification detail. In practice, what the programmer sees is what @jdalton reported: attempt to define an own property on a primitive fails, just as for frozen objects.

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Dec 22, 2015

Member

But 9.1.9 returns that false to step 6.c of 6.2.3.2 which only throws for strict references.

@claudepache is correct it would be better if it could always throw, but that isn't the legacy semantics outside of strict mode. But strict mode does give the more desirable error behavior.

Member

allenwb commented Dec 22, 2015

But 9.1.9 returns that false to step 6.c of 6.2.3.2 which only throws for strict references.

@claudepache is correct it would be better if it could always throw, but that isn't the legacy semantics outside of strict mode. But strict mode does give the more desirable error behavior.

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