When does *not* using new work on built-ins? [dupl

2020-04-04 05:48发布

问题:

Playing with built-in JavaScript objects and constructors, I noticed something a little odd.

Sometimes, it's possible to get new objects by calling a constructor without new. For example:

> new Array(1,2,3,4)
[1, 2, 3, 4]
> Array(1,2,3,4)
[1, 2, 3, 4]

But sometimes this doesn't work:

> Date()
"Thu Jun 05 2014 00:28:10 GMT-0600 (CST)"
> new Date()
Date 2014-06-05T06:28:10.876Z

Is the behavior of non-new constructor built-in functions defined anywhere in the ECMAScript specification? Note that this behavior is actually useful; I can make a non-sparse copy of an array by calling Array.apply(arr), but I'd only feel comfortable doing that if it were cross-platform.

回答1:

The behaviour of a native method depends on the EcmaScript specification.

For Date the spec says :

When Date is called as a function rather than as a constructor, it returns a String representing the current time (UTC).

NOTE : The function call Date(…) is not equivalent to the object creation expression new Date(…) with the same arguments.

and for Array the spec says

When Array is called as a function rather than as a constructor, it creates and initialises a new Array object.

Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.

So how it works with or without the new keyword is completely dependant on what method you're using, and what the spec says should happen when called without the new keyword.

For instance, the Math object is different again

The Math object does not have a [[Construct]] internal property; it is not possible to use the Math object as a constructor with the new operator.



回答2:

Yes, ECMA-262 (I am using 5.1 Edition for reference) does define how should object constructors behave when called with or without the new keyword.

For Array:

15.4.1 The Array Constructor Called as a Function:

When Array is called as a function rather than as a constructor, it creates and initialises a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.

15.4.2 The Array Constructor:

When Array is called as part of a new expression, it is a constructor: it initialises the newly created object.

For Date:

15.9.2 The Date Constructor Called as a Function:

When Date is called as a function rather than as a constructor, it returns a String representing the current time (UTC).
The function call Date(…) is not equivalent to the object creation expression new Date(…) with the same arguments.

15.9.3 The Date Constructor:

When Date is called as part of a new expression, it is a constructor: it initialises the newly created object.