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.
Why "new function" calls the function?
-
21-09-2022 - |
Question
I was just playing with Date
object and I observed this
- new Date() // returns Date object
- 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.
Solution
OTHER TIPS
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.
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:
- Let ref be the result of evaluating NewExpression.
- Let constructor be GetValue(ref).
- If Type(constructor) is not Object, throw a TypeError exception.
- If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
- 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:
- Let ref be the result of evaluating MemberExpression.
- Let constructor be GetValue(ref).
- Let argList be the result of evaluating Arguments, producing an internal list of argument values (11.2.4).
- If Type(constructor) is not Object, throw a TypeError exception.
- If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
- Return the result of calling the [[Construct]] internal method on constructor, providing the list argList as the argument values.