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)) {
    // A legit Map but has uninitialized [[MapData]]
    %MapInitialize(this);
  } else {
    // [[MapData]] is present but is already initialized
    throw TypeError("Attempted to reinitialize a Map");
  }
}


The main point of introducing @@create (I think) was to allow for distinguishing between initializing, initialized, and everything else.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to