williamsandonz
williamsandonz

Reputation: 16420

What is the difference between the two OO methodologies in javascript?

I've been using the below, I've seen other code using function() { } and then using the this keyword, what is the difference here, have I actually instantiated an object below?

    var MyObj = {
 propertyOne: 'a',
            Method: (function() {
                function MyFuncOne() {}
                function MyFuncTwo() {}
                return {
                    MyFuncOne: MyFuncOne,
                    MyFuncTwo: MyFuncTwo
                }
            })()
        }

Upvotes: 1

Views: 107

Answers (3)

jfriend00
jfriend00

Reputation: 707318

The only reason I can think of for doing something like this is if you wanted to have some private variables that were shared between the two functions (after changing it to make it legal javascript):

var MyObj = (function() {
        var x,y,z;    // these will be accessible only to 
                      // the MyFuncOne and MyFuncTwo functions
        function MyFuncOneA() {}
        function MyFuncTwoA() {}
        return {
            MyFuncOne: MyFuncOneA,
            MyFuncTwo: MyFuncTwoA
        }
    })();

I had to change your syntax to even make it work because as you had it myObj = {{...}} which isn't very useful and may have not even been valid.

Other than this private, but shared variables notion, it's just extra (and confusing) syntax for declaring two methods on an object which there are much clearer ways to do.

If you weren't using the private variables, then the above example is functionally the same as this much simpler syntax which makes a lot more sense to me:

var MyObj = {
    MyFuncOne: function() {},
    MyFuncTwo: function() {}        
};

Upvotes: 2

gilly3
gilly3

Reputation: 91497

Using a function with the this keyword allows you to do some more things than are possible (or, at least, easy) with an object literal (which is what your anonymous function above returns). Most commonly, creating "types".

function Animal () { }
Animal.prototype.speak = function () {
    return "";
};
var dog = new Animal();
dog instanceof Animal;    // returns true 

This also makes inheritance easier:

function Feline () { }
Feline.prototype = new Animal;
Feline.prototype.speak = function () {
    return "meow";
};
function Lion () { }
Lion.prototype = new Feline;
Lion.prototype.speak = function () {
    return "roar";
};
function Cat () { }
Cat.prototype = new Feline;
var leo = new Lion();
var baxter = new Cat();
leo.speak();       // returns "roar"
baxter.speak();    // returns "meow" - from prototype chain
leo instanceof Feline;   // returns true 
leo instanceof Animal;   // returns true
leo instanceof Cat;      // returns false

Demo: http://jsfiddle.net/hEnJf/

Upvotes: 1

tjdett
tjdett

Reputation: 1723

Yes, you've instantiated a "singleton" object with two methods.

I believe the outer curly braces are unnecessary, and you could just write:

var MyObj = 
    (function() {
        function MyFuncOne() {}
        function MyFuncTwo() {}
        return {
            MyFuncOne: MyFuncOne,
            MyFuncTwo: MyFuncTwo
        };
    })();

Another way to do it is:

var MyObj = 
    (function() {
        var obj = {};
        obj.MyFuncOne = function() {};
        obj.MyFuncTwo = function() {};
        return obj;
    })();

Wrapping your JS in (function() { /* code here */ })() is good practice for preventing variables leaking into global scope. In this case, you're using it to assemble an object.

Upvotes: 2

Related Questions