7

In JavaScript, I was wondering if there is anything special about new or if it is just syntactic sugar for call(). If I have a constructor like:

function Person ( name, age ){
    this.name = name;
    this.age = age;
}

is

var bob = new Person( "Bob", 55 );

any different than

var bob;
Person.call( bob = new Object(), "Bob", 55 );

?

Sled
  • 18,541
  • 27
  • 119
  • 168
  • 2
    They are not equivalent, the equivalent version would be `Person.call( bob = Object.create(Person.prototype), "Bob", 55 );`. Is it syntactic sugar? Might depend on how you define it. `Object.create` was not available in earlier JS versions. – Felix Kling Jan 29 '13 at 15:48
  • @FelixKling probably should make that an answer instead of a comment, it's a good one. :) – Sled Jan 29 '13 at 15:58

6 Answers6

4

They are not equivalent in your example, because bob does not inherit from Person.prototype (it directly inherits from Object.prototype).

The equivalent version would be

Person.call(bob = Object.create(Person.prototype), "Bob", 55 );

Is it syntactic sugar? Might depend on how you define it.

Object.create was not available in earlier JS versions, so it was not possible to set up object inheritance without new (you are able to overwrite the internal __proto__ property of an object in some browsers, but that is really bad practice).


As a reference, how new works is defined in http://es5.github.com/#x11.2.2 and http://es5.github.com/#x13.2.2. Object.create is described in http://es5.github.com/#x15.2.3.5.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
2

No, new is not just syntactic sugar. On the contrary, Person.call works (and only works) to construct a new instance because JavaScript allows constructors to be called without new in some cases.

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
2

No.

call() merely invokes a function (see also apply()) whereas the new keyword initializes an object from a prototype.

While it's true that a prototype constructor is a function, it's a special case.

Sled
  • 18,541
  • 27
  • 119
  • 168
buley
  • 28,032
  • 17
  • 85
  • 106
2

No, it's not. If your first example, you are actually creating a Person.

bob instanceof Person == true

In the other example...

bob instanceof Person == false
mako-taco
  • 722
  • 5
  • 10
1

The point of creating an instance of a type is to share some behavior, usually through the prototype.

Let's say you add a function :

Person.prototype.doSomething = function(){
   ...
}

Then this function will be available for all objects created as instances of Person using new, but not to the object you create using call.

The MDN has a good introductory document about the use of the prototype.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
1

When you call new, you are invoking the function as a constructor. This tells JavaScript, to make a "new" Person object, and then call the function with that new object set as this.

In your 2nd example, you are calling the function normally, and manually setting this to a new Object (or just {}). So, the function runs, and sets properties of the this object you sent it. (Try just doing Person( "Bob", 55 );, then console.log(window.name))

In the 1st example, bob is a Person object; but in the 2nd, it's an Object.

So, no, one is not short for the other. They are different.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337