toLocaleString in Object and Array

# Norbert Lindenberg (10 years ago)

All ECMAScript objects have a toLocaleString method, originally defined in Object.prototype and overridden in Array, Number, and Date. The parameter list of this method has changed over time:

  • In ES3 and ES5, the methods don't take parameters, but there's a note "The first parameter to this function is likely to be used in a future version of this standard; it is recommended that implementations do not use this parameter position for anything else."

  • In ECMA-402 first edition, we respecified Number.prototype.toLocaleString and Date.prototype.toLocaleString to take two parameters (locales and objects).

  • In the current draft of ES6, the specs for these two methods are changed to reserve the two parameter positions and to require that they're either used as specified in ECMA-402 or not used for any other purpose.

That leaves the toLocaleString methods in Object and Array somewhat incompatible with Number and Date: Their specs still reserve the first parameter, but not the second. And Array.prototype.toLocaleString, which calls toLocaleString on all elements of an array, does not pass on any arguments, thus breaking localization for any Number or Date objects the array may contain.

I can see the following ways to resolve this:

  • Remove the notes about the first parameter on toLocaleString in Object and Array, and accept that they will not be properly localized. Most compatible, least localization friendly.

  • Reserve the first two parameters on toLocaleString in Object and Array, and specify that they must always be ignored in Object, and always be passed on to the toLocaleString calls on the elements in Array. One issue here is that the toLocaleString methods on Number and Date throw exceptions if provided invalid arguments, so a call to Array.prototype.toLocaleString can result in an exception if a Number or Date instance is present in the array while completing normally otherwise.

  • Reserve the first two parameters on toLocaleString in Object and Array, allow a future version of ECMA-402 to specify how to use them, and require that the parameters are ignored in ES6 implementations that don't also implement a version of ECMA-402 specifying their use. The next version of ECMA-402 could then require a stricter implementation that always checks locales and options.localeMatcher for validity, even when called on an empty array or object, and passes the parameters on to an array's elements.

Thoughts about the best way to proceed?

Thanks, Norbert

# Andrea Giammarchi (10 years ago)

FWIWI, toString, as well as toLocaleString in the Object.prototype, has been used as a hack to bring non-enumerable properties in Internet Explorer 8 and lower.

I am not sure what will be, but if anything to not break the web, should consider this fact, even if not concerned as I am about IE8 usage in 2014.

# Claude Pache (10 years ago)

It should be ensured that the default implementation of Array.prototype.toLocaleString will always produce consistent localisations for both the list separator (by default ,) and the array elements. For instance, the array [1.2, 3] might be transformed, under .toLocaleString, into "1.2,3" (English localisation for both the numbers and the list separator), or into "1,2;3" (French localisation for both the numbers and the list separator), but should never be transformed into"1,2,3"` (hybrid localisation that yields an illegible result).

Therefore, if Array.prototype.toLocaleString is able to interpret its arguments in order to produce a correct localisation of the list separator, then it should forward these arguments when invoking .toLocaleString on its elements. But if it is not able to interpret them, it should not forward them.

In conclusion, among the three proposed solutions, the second one should be avoided because of the issue of inconsistent localisations. The third one seems reasonable because it allows Array.prototype.toLocaleString to be properly specified by ECMA-402.

# Brendan Eich (10 years ago)

Claude Pache wrote:

In conclusion, among the three proposed solutions, the second one should be avoided because of the issue of inconsistent localisations. The third one seems reasonable because it allows Array.prototype.toLocaleString to be properly specified by ECMA-402.

+1.

# Allen Wirfs-Brock (10 years ago)

On Dec 10, 2013, at 9:55 PM, Norbert Lindenberg wrote:

All ECMAScript objects have a toLocaleString method, originally defined in Object.prototype and overridden in Array, Number, and Date. The parameter list of this method has changed over time:

  • In ES3 and ES5, the methods don't take parameters, but there's a note "The first parameter to this function is likely to be used in a future version of this standard; it is recommended that implementations do not use this parameter position for anything else."

  • In ECMA-402 first edition, we respecified Number.prototype.toLocaleString and Date.prototype.toLocaleString to take two parameters (locales and objects).

  • In the current draft of ES6, the specs for these two methods are changed to reserve the two parameter positions and to require that they're either used as specified in ECMA-402 or not used for any other purpose.

That leaves the toLocaleString methods in Object and Array somewhat incompatible with Number and Date: Their specs still reserve the first parameter, but not the second. And Array.prototype.toLocaleString, which calls toLocaleString on all elements of an array, does not pass on any arguments, thus breaking localization for any Number or Date objects the array may contain.

I can see the following ways to resolve this:

  • Remove the notes about the first parameter on toLocaleString in Object and Array, and accept that they will not be properly localized. Most compatible, least localization friendly.

  • Reserve the first two parameters on toLocaleString in Object and Array, and specify that they must always be ignored in Object, and always be passed on to the toLocaleString calls on the elements in Array. One issue here is that the toLocaleString methods on Number and Date throw exceptions if provided invalid arguments, so a call to Array.prototype.toLocaleString can result in an exception if a Number or Date instance is present in the array while completing normally otherwise.

  • Reserve the first two parameters on toLocaleString in Object and Array, allow a future version of ECMA-402 to specify how to use them, and require that the parameters are ignored in ES6 implementations that don't also implement a version of ECMA-402 specifying their use. The next version of ECMA-402 could then require a stricter implementation that always checks locales and options.localeMatcher for validity, even when called on an empty array or object, and passes the parameters on to an array's elements.

Thoughts about the best way to proceed?

So why didn't the first edition of ECMA-402 provide a new definition for Array.prototype.toLocaleString? Was that intentional or an oversight? It think it should and it should probably do so in a new edition of 402 that is released simultaneously with ES6 (there are probably a few other minor ES6 related cleanups that should also be incorporated). Then ES6 could handle A.p.toLocaleString exactly like it is handling N.p.toLocaleString and D.p.toLocaleString.

WRT O.p.toLocaleString it is essentially a fall back implementation for objects that don't have any locale specific toString behavior. I don't think it should every be over-ridden by ECMA-402. Since that default implementation doesn't use the arguments, I don't know if there is any need to specify them. Perhaps I should provide a NOTE that essentially says this.

# Norbert Lindenberg (10 years ago)

On Dec 11, 2013, at 11:43 , Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

So why didn't the first edition of ECMA-402 provide a new definition for Array.prototype.toLocaleString? Was that intentional or an oversight?

I don't remember it ever coming up in our discussions, so an oversight, or negligence.

It think it should and it should probably do so in a new edition of 402 that is released simultaneously with ES6 (there are probably a few other minor ES6 related cleanups that should also be incorporated). Then ES6 could handle A.p.toLocaleString exactly like it is handling N.p.toLocaleString and D.p.toLocaleString.

Sounds reasonable; I've filed ecmascript#2383.

There is a ticket already for alignment of ECMA-402 with ES6 in general; if you come across additional cleanups needed, please add them: ecmascript#1260

WRT O.p.toLocaleString it is essentially a fall back implementation for objects that don't have any locale specific toString behavior. I don't think it should every be over-ridden by ECMA-402. Since that default implementation doesn't use the arguments, I don't know if there is any need to specify them. Perhaps I should provide a NOTE that essentially says this.

The note should probably mention that there are overrides that expect specific parameter values for the first two parameters.