Brendan Eich (2013-07-16T23:56:03.000Z)
Brandon Benvie wrote:
> On 7/16/2013 4:10 PM, Erik Arvidsson wrote:
>> All of the new constructors, Map, Set, WeakMap and WeakSet should fail
>> when called as a function unless `this` already has a certain internal
>> property, ie [[MapData]]. This is so that sub classing works as
>> expected.
>>
>> However, all JS engines that supports Map, Set and WeakMap are future
>> hostile and they all return a new instance when called as a function.
>> For example, here is the V8 code:
>>
>> function MapConstructor() {
>>    if (%_IsConstructCall()) {
>>      %MapInitialize(this);
>>    } else {
>>      return new $Map();
>>    }
>> }
>>
>> I understand that fully supporting @@create requires a lot of work but
>> until then we should at least throw when called as function to allow
>> us to get out of this mess eventually.
>>
>
> I wonder if the current spec language is a remnant of before @@create 
> was added to the spec. It should be possible to detect when the 
> constructors are called with a receiver that is not an initializing 
> instance and simply create a new instance. Pseudo code:
>
> function Map(...args){
>   if (!IsObject(this) || !%HasMapData(this)) {
>     // got a primitive, the global object, or some random object like 
> from `Map.call({})`
>     return new Map(...args);
>   } else if (!%IsInitializedMap(this)) {

Nit: else after return ;-).

More substantive: Mark's suggestion seems better because it throws on 
random wrong this but supports strict calls by unqualified name.

/be
domenic at domenicdenicola.com (2013-07-18T16:32:37.604Z)
Brandon Benvie wrote:
> I wonder if the current spec language is a remnant of before @@create 
> was added to the spec. It should be possible to detect when the 
> constructors are called with a receiver that is not an initializing 
> instance and simply create a new instance. Pseudo code:
>
> ```js
> function Map(...args){
>   if (!IsObject(this) || !%HasMapData(this)) {
>     // got a primitive, the global object, or some random object like from `Map.call({})`
>     return new Map(...args);
>   } else if (!%IsInitializedMap(this)) {
> ```

Nit: else after return ;-).

More substantive: Mark's suggestion seems better because it throws on 
random wrong this but supports strict calls by unqualified name.