2

Lets say I have some constructors:

function Foo() { }
function FooObject() { return {} }
function FooArray() { return [] }
function FooFunction() { return function () {} }
function FooString() { return '' }
function FooNumber() { return 1337 }

And I use them to create some objects:

new Foo() // creates Foo instance
new FooObject() // creates object
new FooArray() // creates array
new FooFunction() // creates function

Those make sense, but strings and numbers just end up as instances, why?

new FooString() // creates FooString instance: WAT
new FooNumber() // creates FooNumber instance: WAT

Why is this?

alt
  • 13,357
  • 19
  • 80
  • 120
  • Just a question: are you using `new` intentionally and consciously? See http://stackoverflow.com/questions/383402/is-javascript-s-new-keyword-considered-harmful This is not a loaded question; I'm just making sure you realize its implications. – David J. Dec 16 '13 at 19:37
  • 4
    Well... First of all, don't do that. Constructors should be used to create instances of the constructor type, not to return primitives. It doesn't make any sense to return a primitive from a constructor... Constructors return objects. – sbking Dec 16 '13 at 19:41
  • `function FooString() { return new String('') }` :) – Yury Tarabanko Dec 16 '13 at 19:45
  • @Cuberto that was not the question. I am aware there's no reason to do it. I'm asking why the language performs the way it does. – alt Dec 17 '13 at 16:29

2 Answers2

5

Here is the description of the behaviour you are interested in: http://bclary.com/2004/11/07/#a-13.2.2

When the [[Construct]] property for a Function object F is called, the following steps are taken:

  1. Create a new native ECMAScript object.
  2. Set the [[Class]] property of Result(1) to "Object".
  3. Get the value of the prototype property of F.
  4. If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
  5. If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1.
  6. Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
  7. If Type(Result(6)) is Object then return Result(6).
  8. Return Result(1).
Vitalii Petrychuk
  • 14,035
  • 8
  • 51
  • 55
1

Strings and numbers in JavaScript are primitive types, which are immutable. And, because the new operator instantiates a new object that is an instance of the given constructor function, you get an object instead of the primitive value. If you called those functions without the new operator, you would get the primitive values as you'd expect.

See the MDN article on the new operator.

caleb531
  • 4,111
  • 6
  • 31
  • 41
  • "the new operator always instantiates a new object that is an instance of the given constructor function" -- are you sure? – Dagg Nabbit Dec 16 '13 at 19:43