Default @@toStringTag for user classes
Le 2 déc. 2014 à 09:04, Michał Wadas <michalwadas at gmail.com> a écrit :
It probably would be backward incompatible change. Too much code depends on [Object Object].
I'm curious to know what sort of code would be broken by O.p.toString.call(x) === "[object Point]"
for instances x
of some user-defined class? and whether it is not already broken by, say, O.p.toString.call(new Set) === "[object Set]"
?
Same question here.
AFAIK usually the ({}.toString.call(generic) === "[object Object]")
check
is the default:
in a switch, the last else
in a flow, etc etc ...
although I wouldn't be surprised if some code, somewhere, would do strict
comparison to know if it's a user defined object or not. In that case there
will be problems.
To be honest I also don't see much advantage in having this configurable
when obj.constructor.displayName
or obj.constructor.name
can be checked
instead and eventually fallback into Object.prototype.toString.call(obj)
This will work backward compatible too
br
Le 2 déc. 2014 à 08:46, Dmitry Soshnikov <dmitry.soshnikov at gmail.com> a écrit :
Hi,
Probably worth providing a default implementation of the
@@toStringTag
when evaluating a class [1]. In this case users will be able to do:class Point { ... } var p = new Point(1, 2); console.log(p); // "[object Point]"
You seem to imply that console.log(p)
will show the result of p.toString()
in the console. But it is not the case for the majority of browsers.
I've just tried:
var Point = function() {}
Point.prototype.toString = function() { return "(this is an object of type Point)" }
console.log(new Point)
Results are:
Firefox: Object { } Chrome: Point{toString: function} Safari: Object IE: [object Object] (this is an object of type Point)
In particular, note that Chrome doesn't need the help of .toString()
in order to log useful information.
The difference between "[Object Point]" and "[Object Set]" is fundamental. Your application would not change any behavior without explicit creating "new Set". But changing behavior of existing code is something different - it can introduce subtle bugs in enclosed environment. 2 gru 2014 13:03 "Claude Pache" <claude.pache at gmail.com> napisał(a):
I think by @@toStringTag
he meant the ability to define a [[Class]]
name so that {}.toString.call(generic)
would return such name instead of
Object
but I'm sure Dmitry will come back explaining and/or asking more.
From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Andrea Giammarchi
I think by
@@toStringTag
he meant the ability to define a[[Class]]
name so that{}.toString.call(generic)
would return such name instead ofObject
but I'm sure Dmitry will come back explaining and/or asking more.
[[Class]] does not appear in the spec, and @@toStringTag does.
From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Michal Wadas
But changing behavior of existing code is something different - it can introduce subtle bugs in enclosed environment.
Nobody is proposing changing the behavior of existing code. They are proposing changing the behavior of class syntax, and there is no existing code that uses class syntax.
On Tue, Dec 2, 2014 at 9:56 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
I think by
@@toStringTag
he meant the ability to define a[[Class]]
name so that{}.toString.call(generic)
would return such name instead ofObject
but I'm sure Dmitry will come back explaining and/or asking more.
Yeah, so basically current O.p.toString
[1] in step 14 delegates to the
@@toStringTag
. Which means user-classes have ability to ad-hoc the result
of using default toString
from O.p
.
In a class users have to put it manually at the moment:
class Point {
constructor(x, y) {
this._x = x;
this._y = y;
}
toString() {
return '<Point ' + this._x + ', ' + this._y + '>';
}
[Symbol.toStringTag]() {
return 'Point';
}
}
var p = new Point(10, 20);
console.log(p.toString()); // '<Point 10, 20>'
console.log(({}).toString.call(p)); // '[object Point]'
Notice how the implementation defines its own toString
, and at the same
time provides the ability to test the type tag with the O.p.toString
.
So my proposal is to provide default implicit implementation of that
Symbol.toStringTag
method (which is @@toStringTag
in the spec).
Dmitry
[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring
On Tue, Dec 2, 2014 at 5:12 PM, Dmitry Soshnikov <dmitry.soshnikov at gmail.com
wrote:
On Tue, Dec 2, 2014 at 9:56 AM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
I think by
@@toStringTag
he meant the ability to define a[[Class]]
name so that{}.toString.call(generic)
would return such name instead ofObject
but I'm sure Dmitry will come back explaining and/or asking more.Yeah, so basically current
O.p.toString
[1] in step 14 delegates to the@@toStringTag
. Which means user-classes have ability to ad-hoc the result of using defaulttoString
fromO.p
.In a class users have to put it manually at the moment:
class Point { constructor(x, y) { this._x = x; this._y = y; } toString() { return '<Point ' + this._x + ', ' + this._y + '>'; } [Symbol.toStringTag]() { return 'Point'; }
This one seems should be a getter actually based on the algorithm of
O.p.toString
:
get [Symbol.toStringTag]() {
return 'Point';
}
Dmitry
Probably worth providing a default implementation of the
@@toStringTag
when evaluating a class [1]. In this case users will be able to do:The default implementation will be just (if the
className
is defined of course):[1] people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-classdefinitionevaluation
Dmitry