5

What is the difference between creating an object using an inline object constructor and creating an object by immediately invoking a contructor? I have always done the latter as it free's me from having to call something like init() myself and feels like the right thing to do, but I keep seeing the object notation in other people's code and was wondering if there is another difference I am not seeing.

Example:

window.fooModule = {

  init: function() {
    this.bar = "cee";    
    doStuff();
  },

  doStuff: function() {
    ...
  }
}

window.fooModule.init();

Example2:

window.fooModule = new function(){
  this.bar = "Cee";

  this.doStuff = function() {
    ...
  }


  this.doStuff();
}
  • 1
    The second one [is absolutely horrible](http://stackoverflow.com/q/10406552/1048572) and should never be used – Bergi Sep 09 '16 at 12:38
  • Oh, that's silly, removed the flag, carry on! – roberrrt-s Sep 09 '16 at 12:42
  • The difference is that `doStuff()` in the first one will fail with a name error. – deceze Sep 09 '16 at 12:52
  • I'm also not sure what you're looking for as answer. One is using literal object notation, the other is using the object instantiation mechanism `new`. They're very different things. You get sort of the same result in the end, yes. There are infinitely more variations you could come up with to get the same end result, but there's little point in enumerating them all. – deceze Sep 09 '16 at 12:54

3 Answers3

1

In first notation variable fooModel is object created without constructor call, in second notation fooModel is object created with call of constructor as anonymous function, so when using new keyword constructor function is called and object is created from its prototype ( in this example no prototype is declared so it is standard object prototype).

Conclusion

Use second notation if Your object has to call some code when is created, use first if not.

More about second notation

Second notation enables also using local ( private ) variables and functions inside constructor, because constructor give us own scope.

var obj=new function(){

  var priv="Local scope variable";

  var method=function(){

    console.log("Local method");
  };

  this.doStuff=function(){

     //here local methods and variables can be used
  };
};

Second notation with constructor and new is more often used with standard constructor function declaration and prototype declaration. This is correct way if We need to create more then one object. Methods and every shared properties should be declared in prototype not in constructor.

var ExampleClass=function(bar){

   //constructor
   this.bar = bar;
};

ExampleClass.prototype.doStuff=function(){

};

Creating such object:

var a=new ExampleClass("A bar"); //a.bar is "A bar"
var b=new ExampleClass("B bar"); //b.bar is "B bar"

Objects a and b have the same prototype ( it saves memory ) but they can have different properties set in constructor.

OffTop

In javascript is so many possibilities to create objects, I have third example how run code in first notation:

window.fooModule = {

  init: function() {
    this.bar = "cee";    
    this.doStuff();

    return this;//return this
  },

  doStuff: function() {

  }
}.init();//run init after object notation

I create object and run init in one time.

Maciej Sikora
  • 19,374
  • 4
  • 49
  • 50
  • Your evaluation is correct, but I disagree with your conclusion. One should **never use the second notation**. If you need to execute some code during creation, use an IIFE (like in the module pattern). – Bergi Sep 09 '16 at 13:09
  • Thanks, but my point is that `new` should only be used when there a multiple instances to be created, and never for a single object only, even if there is code to be executed. – Bergi Sep 09 '16 at 13:37
-1

let the 1st example return obj1 and 2nd example return obj2

obj1 will have [[Prototype]] is an object. This object has constructor property is "function Object()"

obj2 will have [[Prototype]] is an object. This object has constructor property is anonymous function.

The way in 2nd example is usually used to achieve something we call "singleton"

Bonus: This stuff is easy to confused, but if you want to dig deeper, here is a good post for you

https://zeekat.nl/articles/constructors-considered-mildly-confusing.html

Khoa
  • 2,632
  • 18
  • 13
  • 1
    The first pattern creates a singleton object just as well. – Bergi Sep 09 '16 at 13:11
  • What do you mean by "*[[Prototype]] is an object*"? And are you suggesting the result are not actually that different? – Bergi Sep 09 '16 at 13:12
  • on javascript, you cannot direct access to prototype of object. However, you can access prototype of a function. [[Prototype] is just the way I use to mention that object's unaccessible prototype and easy to compare with function's accessible prototype – Khoa Sep 09 '16 at 13:15
  • I know what the [[prototype]] notation means (and that you can directly access it by using `Object.getPrototypeOf`), but what are you comparing it with in your answer? "is an object" isn't particularly helpful, there are very very few objects for which this doesn't hold. – Bergi Sep 09 '16 at 13:19
  • the difference between them is at bold parts. – Khoa Sep 09 '16 at 13:22
  • OK, but that isn't the important difference. – Bergi Sep 09 '16 at 13:35
-1

There are objects and there are object definitions prototypes. Neither of your examples are object definitions prototypes.

window.fooModule = function(bar){
  this.bar = bar;

  (this.doStuff = something => {
    console.log(this.bar,'is doing', something || 'something');
  })();
};

[a,b]= [new fooModule('a'), new fooModule('b')];

If you simply want to create an object, then you can skip the new and this operator.

(window.fooModule = {
  bar : 'Cee',
  doStuff : something => {
    console.log(foo.bar,'is doing', something || 'something');
  }}).doStuff();
Hin Fan Chan
  • 1,543
  • 10
  • 11