`new Object` vs `Object` difference
I think historically Array
, Function
, and Object
can be used with or
without new
and the result is exactly the same ... since, about, ever.
Agreed if that's actually indeed the case, we could have just one definition for those 3 constructors (not just Object)
Thanks, Array and Function (as well as RegExp) actually directly specify
that calling them with and without new produces equivalent results where
Object
doesn't and actually has a hole (in what it may do to host
objects).
It's just baffling that Object
is defined so differently. I wonder if
there are old browsers that differ on this, or there is a bigger reason for
this behaviour.
Yep, RegExp too, you are right. The only caveat that might comes to my mind
is dealing with foreigner objects ( through plugins such Java applets and
stuff ) where maybe there is a difference, but I've no memory of any sort
of real-world use case based on the fact that new
was mandatory.
Indeed if you try even minifiers, you'll notice that code like this
this.bla = new Object(parent.foreignObject);
will be minified as
this.bla=Object(parent.foreignObject);
ES6 eliminates the (possible) special treatment of host objects passed as the argument to the Object constructor. As far as anybody seems to know, no implementation had ever made use of that allowance.
The ES6 spec. also unifies the [[Call]] and [[Constructor]] behavior of Object into a single algorithm people.mozilla.org/~jorendorff/es6-draft.html#sec-object-value ES6 unifies all [[Call]] and [[Construct]] algorithms for built-in constructors in this same manner.
That's good to know and it's good to know I'm not the first one to spot this.
While we're visiting the spec on that:
Why is it specified that "When called as a constructor it creates a new ordinary object. When Object is called as a function rather than as a constructor, it performs a type conversion." - wouldn't it make more sense to remove that or specify "behaves the same way"?
Where is it actually explained what Object does when called as a constructor?
The difference - at least in the phrasing of Object vs Array seems to be just as present in the latest spec draft from what I can tell.
On Jun 12, 2015, at 2:47 PM, Benjamin Gruenaum wrote:
That's good to know and it's good to know I'm not the first one to spot this.
While we're visiting the spec on that:
Why is it specified that "When called as a constructor it creates a new ordinary object. When Object is called as a function rather than as a constructor, it performs a type conversion." - wouldn't it make more sense to remove that or specify "behaves the same way"?
yes, probably
Where is it actually explained what Object does when called as a constructor?
It doesn't because the behavior is seem in both cases.
Step 1 of people.mozilla.org/~jorendorff/es6-draft.html#sec-object-value is looking for the case of a super()
call from a subclass constructor.
The difference - at least in the phrasing of Object vs Array seems to be just as present in the latest spec draft from what I can tell.
Yes, the Object description still contains some ancient language that should probably be removed in the future as it adds not (except perhaps confusion) to the spec.
JS is very much like writing with a pen (traditionally speaking). We can only try to make less errors as we move forward, but what’s there it’s there and it’s either too expensive or impossible to change.
Pointing out that I'm replying to a message with an empty subject - using the correct original title here
---------- Forwarded message ---------- From: Rock <zloirock at zloirock.ru>
Benjamin Gruenaum, Andrea Giammarchi, you are wrong about RegExp:
var re = /./;
new RegExp(re) === re; // false
RegExp(re) === re; // true
Nice catch. This is states explicitly as a difference to the rule here
http://es5.github.io/#x15.10.3.1
> If pattern is an object R whose [[Class]] internal property is "RegExp"
and flags is undefined, then return R unchanged. Otherwise call the
standard built-in RegExp constructor (15.10.4.1) as if by the expression
new RegExp( pattern, flags) and return the object constructed by that
constructor.
I didn't notice that - thanks.
Ok, so I gave this a few hours in the open.
So, I'm looking at the ES5 specification (also checked the current ES draft which is similar) at the definition of what new Object and Object do. To my surprise:
new Object
describes a whole algorithm of how the object constructor works - treating what happens with different kinds of values. Basically callsToObject
on non objects - identity on objects and builds on null and undefined.Object
has a special first step for null and undefined where it builds an object and then callsToObject
on primitives and identity on objects.After reading the description a few times - they seem identical. However, clearly from the spec they do something different. For example in Array - calling new Array is specified as the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.`
The only difference I've been able to identify with the help of a friend is that the behaviour can be different on host objects. Where
Object
must return the same host object andnew Object
may return the same host object.I've taken a look at the ES3 specification and it too uses the same definition so I suspect this is something that has been there for a long time.
Object
andnew Object
specified differently?Sorry if I'm missing something obvious.
Originally asked on Stack Overflow - stackoverflow.com/q/30801497/1348195