+++ This bug was initially created as a clone of Bug #3544 +++
[removing noise of Bug #3544]
19.1.1.1 Object([ value ])
As specced in Rev 31, `new Object(foo)`, for foo != null, is now just equivalent to `new Object()` instead of ToObject(foo).
One should revert to the definition of Rev 30, that is removing the newly added step 1.
*** Bug 3544 has been marked as a duplicate of this bug. ***
Better fix: modify step 1 the following way:
1. If NewTarget is neither null nor the active function object, then,
a. Return etc.
fixed in rev32 editor's draft
(In reply to Allen Wirfs-Brock from comment #3)
> fixed in rev32 editor's draft
I assume this was changed in the following way. Correct?
---
1. If NewTarget is null, let newTarget be the active function object, else let newTarget be NewTarget.
2. If value is null, undefined or not supplied, return OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%" ).
3. Return ToObject(value).
---
(In reply to André Bargull from comment #4)
Consider:
class Foo extends Object { }
new Foo(3)
With your algorithm you obtain a Number object. I think that the spec intent is to produce an instance of Foo.
(In reply to Claude Pache from comment #5)
> (In reply to André Bargull from comment #4)
>
> Consider:
>
> class Foo extends Object { }
> new Foo(3)
>
> With your algorithm you obtain a Number object. I think that the spec intent
> is to produce an instance of Foo.
Ah I see. What about this solution? Step 3 should handle the Object called from sub-class constructor issue.
---
1. Let activeF be the active function object.
2. If NewTarget is null, let newTarget be activeF, else let newTarget be NewTarget.
3. If SameValue(activeF, newTarget) is false, return OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%").
4. If value is null, undefined or not supplied, return OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%").
5. Return ToObject(value).
---
Here is the algorithm I actually used for Comment 3
1. If NewTarget is neither undefined nor the active function, then,
a. Return OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
2. If value is null, undefined or not supplied, return ObjectCreate(%ObjectPrototype%).
3. Return ToObject(value).
(note the [[call]] state of NewTarget has now been changed from null to undefined)
note that by step 2 we know that NewTarget is either undefined or a Object constructor function, so we can use ObjectCreate instead of OrdinaryCreate...
(In reply to Allen Wirfs-Brock from comment #7)
> note that by step 2 we know that NewTarget is either undefined or a Object
> constructor function, so we can use ObjectCreate instead of OrdinaryCreate...
That means I have to re-open bug 3136. Here's another test case for bug 3136:
---
function cloneWithProto(constructor, prototype) {
return Object.defineProperty(constructor.toMethod({}), "prototype", {value: prototype});
}
for (var constructor of [Object, Array, Date, Error, TypeError, RegExp, String, Boolean, Number]) {
var clone = cloneWithProto(constructor, {});
var obj = new clone();
print(Object.getPrototypeOf(obj) === clone.prototype);
}
---
The above program prints "true" for every constructor function except for `Object`. Changing ObjectCreate to ObjectCreateFromConstructor will align `Object`'s behaviour to be in line with the other built-in constructor functions.
(In reply to Claude Pache from comment #5)
> (In reply to André Bargull from comment #4)
>
> Consider:
>
> class Foo extends Object { }
> new Foo(3)
>
> With your algorithm you obtain a Number object. I think that the spec intent
> is to produce an instance of Foo.
I actually think this should create an `[object Number]` exotic object. The prototype chain will still have Foo.prototype on it.
That would be much more consistent with the rest of the semantics.
class C extends Object {}
is very different from
class C {}
The former has class side inheritance and the instance object is created by calling [[Construct]] on Object with NewTarget passed along.
A similar case would be if I have a base class that might create a typed array in some cases and a plain array in other cases.
(In reply to Erik Arvidsson from comment #9)
> (In reply to Claude Pache from comment #5)
> > (In reply to André Bargull from comment #4)
> >
> > Consider:
> >
> > class Foo extends Object { }
> > new Foo(3)
> >
> > With your algorithm you obtain a Number object. I think that the spec intent
> > is to produce an instance of Foo.
>
> I actually think this should create an `[object Number]` exotic object. The
> prototype chain will still have Foo.prototype on it.
>
Maybe, but I doubt that anyone would willfully construct a Number object without `Number.prototype` in its prototype chain using that syntax. DDWIDM.
fixed in rev32 draft