8

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.

user3629476
  • 170
  • 5
  • Another related question with a similar answer: http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this – Pablo Lozano Jun 05 '14 at 14:34
  • Note: `Date() === new Date().toString()` – Paul Rad Jun 05 '14 at 14:37
  • [What's the difference between Array(1) and new Array(1) in JavaScript?](http://stackoverflow.com/questions/5827008/whats-the-difference-between-array1-and-new-array1-in-javascript) – Habib Jun 05 '14 at 14:37
  • 1
    The behaviour for [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) is in the docs -> `"Note that JavaScript Date objects can only be instantiated by calling JavaScript Date as a constructor: calling it as a regular function (i.e. without the new operator) will return a string rather than a Date object; unlike other JavaScript object types, JavaScript Date objects have no literal syntax."` – adeneo Jun 05 '14 at 14:39
  • For Array it's different, it returns a new instance even when called without the new keyword, so it depends on the native method you're using. – adeneo Jun 05 '14 at 14:40
  • So with builtins, what's the rule? Or is there one? `RegExp` returns a regexp, `Date` returns a string, `Array` returns an array -- aside from `Date`, are there any other built-in constructors that don't return objects? – user3629476 Jun 05 '14 at 14:47
  • P.S. I meant to ask only about built-ins, not about the general behavior of `new`. I edited my question to fit. – user3629476 Jun 05 '14 at 14:48

2 Answers2

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.

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • It would be nice if you could add the behavior of all the built-ins as functions vs. constructors (there are not so many). The reference to the spec is very nice. – user3629476 Jun 05 '14 at 14:51
  • 1
    @user3629476 - Well, there's Date, Array, Object, String, Number, Boolean, Math, RegExp etc. there's quite a few, and the spec says it all, I'm not sure if copying the spec for every built-in would make the answer any better ? – adeneo Jun 05 '14 at 14:54
  • Not to mention at you'd have to update he answer for ES6, ES7, etc. – Felix Kling Jun 05 '14 at 15:48
1

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.

izstas
  • 5,004
  • 3
  • 42
  • 56