String(symbol)
+1. As I already noted last year, as currently specced, ad-hoc debugging code like alert("got argument: " + x)
or alert("got argument: " + String(x))
will throw for symbols, while alert("got argument: " + x.toString())
will throw for null
, undefined
, and Object.create(null)
.
symbol + ''
must continue to throw.
I was suggesting that String(symbol)
should not throw.
This can be spec'ed as String( value ) checking the Type of the value and special case it in case of the value being a symbol.
sounds good to me, I'll update the spec. accordingly
Out of mere curiosity, why is it desired that symbol + ''
throw?
On Aug 13, 2014, at 8:45 AM, Nathan Wall wrote:
Out of mere curiosity, why is it desired that
symbol + ''
throw?
Minimize the chance that somebody might code:
var newName = somePropertyKey+"_stuff";
not realizing that somePropertyKey might be a Symbol. We don't want to silently crete a string property name from a symbol.
With this change, as far as I can tell there's no concise operation directly corresponding to the ToString abstract operation. The best that seems possible is some horribly indirect operation like (v) => Error.prototype.toString.call({ name: v, message: "" })
. That seems undesirable to me. I'm not convinced that having String deviate from ToString is a good thing.
Why would it be useful, from a programmer's perspective, to expose ToString directly? It is just a spec-internal thing, and the reason this change is made is because it is no longer very useful to directly expose that spec-internal thing given how it interacts with symbols.
On 08/26/2014 08:48 AM, Domenic Denicola wrote:
Why would it be useful, from a programmer's perspective, to expose ToString directly?
People will always want to polyfill, or prototype in advance of proposal for standardization. No matter how internal the operation might be, it's heavily used by DOM specs and other similar sorts of things. And I have difficulty seeing why many such APIs would want to stringify incoming symbols, to switch away from using ToString.
Personally, I use the following expression in order to coerce a variable to a string:
var obj = this + ''
and its in-place variant:
x += ''
I think it'll continue to work in ES6.
Agreed, this is the correct-and-most-concise way to do it. It should throw on symbols, that's important.
Having String(sym)
not throw is a win for other reasons Arv identified,
but using String(any)
to invoke ToString is verbose and fragile, because
String could be rebound :-P. Use +''
if you want ToString in the
language, I say.
x+''
produces different results than ToString when x = { toString() { return '5'; }, valueOf() { return 10; } }
On 08/26/2014 09:14 AM, Brendan Eich wrote:
Agreed, this is the correct-and-most-concise way to do it.
It's not the most correct way to do it. a + ""
performs ToPrimitive(a, hint = None), whereas ToString(a) performed ToPrimitive(a, hint = String). The former consults valueOf
, then toString
, the latter the reverse.
using
String(any)
to invoke ToString is verbose and fragile, becauseString
could be rebound :-P.
Generally polyfills are fine with that limitation, and only us language pedants need worry/care about String
being rebound. All the array-method polyfills we've provided on MDN depend on non-rebinding of some builtin function or other. It's not that big a deal.
If x
is an object, x + ''
performs ToString(ToPrimitive(x, <no hint>)), whereas String(x)
performs ToString(ToPrimitive(x, hint String)). So both expressions are not always interchangeable.
Brendan Eich wrote:
Use +'' if you want ToString in the language, I say.
asm.js points the way on other explicit conversion forms:
- ToString(x) is
x+''
- ToNumber(x) is
+x
- ToInt32(x) is
~~x
- ToBoolean(x) is
!!x
Jeff Walden wrote:
It's not the most correct way to do it.
a + ""
performs ToPrimitive(a, hint = None), whereas ToString(a) performed ToPrimitive(a, hint = String). The former consultsvalueOf
, thentoString
, the latter the reverse.
Argh, I had forgotten about the no-hint case there. It seems wrong still, but I forget the details from ES1 era.
Domenic's question of why you want an explicit ToString in the language
remains. If there's a strong reason for it, Reflect.toString
might be
the answer.
Le 26 août 2014 à 17:39, Jeff Walden <jwalden+es at MIT.EDU> a écrit :
On 08/12/2014 11:07 PM, Allen Wirfs-Brock wrote:
sounds good to me, I'll update the spec. accordingly
On Aug 12, 2014, at 7:39 PM, Erik Arvidsson wrote:
I was suggesting that String(symbol) should not throw.
This can be spec'ed as String( value ) checking the Type of the value and special case it in case of the value being a symbol.
With this change, as far as I can tell there's no concise operation directly corresponding to the ToString abstract operation. The best that seems possible is some horribly indirect operation like (v) => Error.prototype.toString.call({ name: v, message: "" }). That seems undesirable to me. I'm not convinced that having String deviate from ToString is a good thing.
Jeff
What about String.prototype.concat?
const ToString = ''.concat.bind('')
Right now String(symbol) throws because it uses ToString which is spec'ed to throw.
I'm suggesting that we special case String(value) to do a type check for Symbol and return the same string as Symbol.prototype.toString.call(value) does.
people.mozilla.org/~jorendorff/es6-draft.html#sec-string-constructor-string-value
The motivation for this is that String(value) is pretty explicit and was in ES5 a safer way to stringify something than value.toString().