0

I know this has been asked many times before, but I still don't quite understand what the difference is between the following:

var Foo =  function (){ //1
     this.a = "";
     this.b = "";
     var c = ""; //private member
   }
var instantiatedFoo = new Foo();

// and the same with closure

 var FooSelfEncapsulated = (function (){//2
   var a = "";
   var b = "";
   var c = "";
   return function (){//3
     this.a = a;
     this.b = b;
   }
 })();
var instantiatedFoo = new FooSelfEncapsulated();

Is there any difference? When would each one be appropriate?

Finally it is good practice to put the same names in the anonymous functions (1,2,3) as shown? Or is it not necessary?

var Foo =  function Foo(){ //1
     this.a = "";
     this.b = "";
     var c = ""; //private member
   }
var instantiatedFoo = new Foo();

// and the same with closure

 var FooSelfEncapsulated = (function FooSelfEncapsulated(){//2
   var a = "";
   var b = "";
   var c = "";
   return function FooSelfEncapsulated(){//3
     this.a = a;
     this.b = b;
   }
 })();
var instantiatedFoo = new FooSelfEncapsulated();
1

You would use the second example if you wanted properties to be different based on some sort of criteria. Because the function is self-calling this isn't quite as useful but you would be able to dynamically change the definition of the object at run time. You may not want to add a function in the actual object because the conditions may change and you want the created objects to be consistent.

A kind of trite example is that say that we want to record if the day of the month at runtime is even or odd:

var FooSelfEncapsulated = (function (){
   var date = new Date();
   var a = date.getDate() % 2 ? "Odd" : "Even";
   var b = "";
   var c = "";
   return function (){//3
     this.a = a;
     this.b = b;
   }
 })();
var instantiatedFoo = new FooSelfEncapsulated();

Doing this, if the code were run on 12/14 11:59:59 all of the FooSelfEncapsulated.a would be "Even". We don't want to do this check in our actual object because the date might have changed and we don't want to keep track of when things happened (or there might be no way to know). We want all of the FooSelfEncapsulated to be same for this particular execution of the program.

The first example, we just define an object and there isn't any chance of having dynamic definitions like this. Having the extra wrapping doesn't really make things clearer.

Having the second example a self-calling function kind of limits the usefulness of this construction a little. However, you are basically defining a factory function for creating the different objects.

As for the naming, it would all depend on how confusing things get. I don't think that there would be a hard rule on this. It would depend on what else is happening. In your examples, it would make sense. However if things get complicated it might be difficult to keep track of.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.