0

I was just playing with Date object and I observed this

  1. new Date() // returns Date object
  2. Date() // returns Date in string format

MDN - Date documentation confirms this

Note: 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.

Tricky part is new Date returns the same result which new Date() returned ?

I tried the same experiment with a normal function,

function f() { console.log(' I am executed'); } new f 

I am surprised to see I am executed gets logged. I am trying to find out the reason why f is called when I did not use execution () operator. Can somebody explain me why new called the method ?

PS: I don't know what new f should have given to me. It was a syntax mistake So I thought it would give me an error. But It does not.

5
  • m59 is right, in javascript function is just another kind of object. Commented Dec 24, 2013 at 18:39
  • 2
    Parentheses are optional when you use the new operator; it's as simple as that. Commented Dec 24, 2013 at 18:50
  • @Pointy Thanks for clarification. Atleast via this I got to learn something about new :) Commented Dec 24, 2013 at 18:52
  • 1
    @Pointy would it be reasonable to say that they are optional because you have to call the constructor for new to work anyway? If not new f wouldn't do anything at all because Function, wouldn't be invoked and so no "new" function object would be created. Correct? Commented Dec 24, 2013 at 18:52
  • 2
    @m59 yes, that's right. It doesn't make sense to use new if you're not calling a function, in other words. I guess one should read a new expression as, "I want to construct an object, and here's an expression that evaluates to a reference to the function I want you to call as the constructor." So calling the function is implicit. The slightly weird part is that if you want to call a function to provide the constructor, you have to parenthesize that. Commented Dec 24, 2013 at 19:00

3 Answers 3

5

Because new will call the constructor of the object you are creating. In the case of a function, the function is both the object and the constructor for that object.

Sign up to request clarification or add additional context in comments.

3 Comments

In case of new f() it should call the constructor of what f() returns. Isn't it? But even then it calls constructor of f only.
@blunderboy using new automatically invokes the constructor. JavaScript objects are different than what you might be used to. You're probably looking for Object.create(). Note that there are also no classes in JavaScript.
This is just the syntax of JavaScript. It's a bit weird if you come from a C#, Java or C++ background.
2

This is a case of a "stupid-proof" code.
As you may know, the new keyword in javascript can be dangerous: for example, say you have a classic Point constructor:

function Point(x, y) { this.x = x; this.y = y; } 

This works as expected if you create a point by instantiating the constructor with the new keyword. But what if someone forgets to use it? What is the result of the following code?

var myPoint = Point(0, 0); 

Well, since the constructor itself doesn't return anything (doesn't even have a return statement), myPoint will be undefined instead of a Point instance. And all because of a forgotten new keyword.
But have no fear! You can write your code to be stupid-proof:

function Point(x, y) { // `this` points to the outer scope // if the function is called witouth `new` if(!(this instanceof Point)) return new Point(x, y); this.x = x; this.y = y; } 

Although functions such as Date, Array and so on are built in and we can actually see their source, I strongly believe that they have this safety mechanism by default to prevent newcomers from making trivial stupid errors.

Comments

2

I think this part of ECMAScript Spec should explain the operation of the new operator. In your case, that's 5 in the first section, and 6 on the second section. Basically, JS will call the constructor like a function.

The new Operator

The production NewExpression : new NewExpression is evaluated as follows:

  1. Let ref be the result of evaluating NewExpression.
  2. Let constructor be GetValue(ref).
  3. If Type(constructor) is not Object, throw a TypeError exception.
  4. If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
  5. Return the result of calling the [[Construct]] internal method on constructor, providing no arguments (that is, an empty list of arguments).

The production MemberExpression : new MemberExpression Arguments is evaluated as follows:

  1. Let ref be the result of evaluating MemberExpression.
  2. Let constructor be GetValue(ref).
  3. Let argList be the result of evaluating Arguments, producing an internal list of argument values (11.2.4).
  4. If Type(constructor) is not Object, throw a TypeError exception.
  5. If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
  6. Return the result of calling the [[Construct]] internal method on constructor, providing the list argList as the argument values.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.