0

How does the new work differently in the 2 examples below? I see that the 2nd example is replacing the annoymous funciton with a variable, but in the second one, the function/class "Person" is actually being called. Does it make any difference if it's being called or not? I tried it without the calling and it still worked. So that led me to believe that new is actually calling the function and setting up this to be assigned to the instance variable.

 var person = new function() {  
        this.setName = function(name) {
            this.name = name;
        }
        this.sayHi = function() {
            return "Hi, my name is " + this.name;
        }
    }
    person.setName("Rafael");  
    console.log(person.sayHi()); // Hi, my name is Rafael  

    var Person = function() {
        this.setName = function(name) {
            this.name = name;
        }
        this.sayHi = function() {
            return "Hi, my name is " + this.name;
        }
    }
    
    var personTwo = new Person()
    
    personTwo.setName("Rafael");
    console.log(personTwo.sayHi()); // Hi, my name is Rafael
prasanth
  • 19,775
  • 3
  • 25
  • 48
stackjlei
  • 7,747
  • 12
  • 42
  • 95
  • There are no classes in javascript (though there is a *class* syntax). How do you intend to create a second instance in the first example? – RobG Oct 27 '16 at 05:36
  • Sort of related to : http://stackoverflow.com/questions/6750880/how-does-the-new-operator-work-in-javascript , and, http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript – PicoCreator Jan 07 '17 at 13:10

3 Answers3

2

There would be almost no difference between these two examples, if it was a simple function like this:

(function() { console.log("IIFE"); })();

// or

var f = function() { console.log("Function"); };
f();

You just store your function in a variable, and then call it.

However, it makes a little difference, since it is related to JS OOP mechanisms. In the first case you get Object instance, and in the second you get Person instance. This makes difference in OOP sense.

var person = new function() { };
console.log("Is instance of: " + person.constructor.name);
console.log("There is no way to check instanceof in this case");

var Person = function() { };
var person = new Person();
console.log("Is instance of: " + person.constructor.name);
console.log(person instanceof Person);

In general, new and classes are supposed to be used as in the second case in order to enable the full functionality of JS OOP. There is absolutely no sense or/and advantage in using anonymous class constructor.

Yeldar Kurmangaliyev
  • 30,498
  • 11
  • 53
  • 87
  • Note that the constructor property and *instanceof* are unreliable ways of determining whether an object is an instance of a particular "class". E.g. `var Fred = Person; var fred = new Fred; fred.constructor.name // Person`. – RobG Oct 27 '16 at 05:45
1

Whether or not it is assigned into a variable: does not matter. It is completely parallel to this example:

var x = 1;
console.log(x);

and

console.log(1);

Whether it needs to be called or not: A function with the new operator is always being called, but with new, parentheses are optional when no parameters are passed: new Person() is equivalent to new Person, but new Person("Joe") cannot be done differently.

Amadan
  • 169,219
  • 18
  • 195
  • 256
1

In the second example, you are passing to the new operator the exact same function. You simply are using a reference (logically stored in a variable) instead of writing literal function just in place.

So, your second example is the same as:

var personTwo = new (function() {  
    [...]
})()
[...]

Which, in fact, is much the same as the first one:

var person = new (function() {  
    [...]
})
[...]

NOTE that the parentheses surrounding the function are absolutely optional in this case. You could be placed there seven if you like: (((((((function(){[...]}))))))).

The point here is that when you say «in the second one, the function/class "Person" is actually being called» you are WRONG there: That function, which acts as a constructor isn't being called by you. You are simply passing it as a parameter (the constructor function) of the new operator which is, in fact, who is actually calling the constructor with the rest of parameters you provided, if any.

See new syntax documentation:

new constructor[([arguments])]

The constructor is the function you pass to the new operator and the parameters are specified between parentheses. But they are fully optional (including the parentheses itself).

This is why new constructor; without parentheses works.

To be clear: What you thought happens (but not) would be written as:

var person = new ((function(){...})()) ();

...or, more verbosely:

    var person = new (
        (function(){ // Constructor builder.
            [...]
            return function(){...}; // Actual constructor.
        })() // Constructor builder call
  //v-- Parentheses to force builder to be called.
    ) (); // <-- Parameters (if any) passed to the constructor.
bitifet
  • 3,083
  • 13
  • 30