Skip to content
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
Closed

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

jdalton opened this issue Dec 22, 2015 · 9 comments

Comments

@jdalton
Copy link
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
Copy link
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
Copy link
Member Author

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 as completed Dec 22, 2015
@claudepache
Copy link
Contributor

line 2 creates a useless wrapper object that is immediately discarded

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

@domenic
Copy link
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
Copy link
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.)

@allenwb
Copy link
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
Copy link
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
Copy link
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.

@allenwb
Copy link
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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants