Is using new in Javascript the same as not using it?


Consider this code:

function klass( z ) {
    this.a = z;
    return this;
}

var b = klass( 5 );
var c = new klass( 9 );

When I run it in Chrome and check in the console, b turns out to be of type DOMWindow, while c is of type klass.

Although both have the property a, effectively both being an instance of klass.

  • Is using or not using new, the same?
  • Is it the same on this example but different in other situations?
  • Are there differences in efficiency or behavior?

When a function is invoked like this

klass(6);  //called function invocation

this will be set to the global object, or, if you're in strict mode, undefined

As a result, the first example (without the new) will return the global object with a new a property attached. In strict mode it will throw an error since this will be set to undefined, and you can't add an a property to undefined.

When you invoke a function with new

new klass( 9 );  //called constructor invocation

the this value is set to a new object, and is implicitly returned from the function—there's no need to say return this

For completeness, when you invoke a function as a method on an object:

foo.method();  //called method invocation

this will be set to the object—foo in this case.

And when you invoke a function with apply (or call)

method.apply(foo)  //called apply invocation 

this is set to whatever you specify—foo again

EDIT

I mentioned strict mode in my answer. A page uses strict mode if it has

"use strict"

at the very top of it.


Without the new your function will just operate on whatever this was bound to, in your case the DOMWindow. No new instance is created, the a property gets set on the window object. Calling the method twice clobbers the previous result.

Try this:

var b = klass(5)
log.info(b.a)
log.info(b == window)  // b is actually the window object
log.info(window.a)   // also 5

var c = klass(6)
log.info(b.a)     // now set to 6
log.info(c == b)  // c and b are the same

It's absolutely not the same:

var a = klass(42);
console.log(a.a); // 42
var b = klass(69);
console.log(b.a); // 69
console.log(a.a); // 69

If you don't call new, you're not getting anything new.