fumeng
fumeng

Reputation: 1820

JS Module Pattern: How to initialize a local object

I'm confused about how to initialize a local object in a JS Module implementation. I have a local variable (an object) that I try and access in the object literal I return; however, when I try to add a new property to that object it says it's undefined. But if I don't then I can easily set the value of the local object to anything else.

Here's my code:

var myModule = (function(){
    var myLocalObj = {}; // I always get a warning in the IDE that this var is never read

    return{
        setObject:function(coll){
            this.myLocalObj = coll; // this works just fine
            this.myLocalObj.newProp = coll.prop // fails because 'myLocalObj' is undefined. 
        },
        getObject:function(coll){
           return this.myLocalObj;
        }
    };
})();

myModule.setObject(obj); // this is what I call after an ajax call is complete

Upvotes: 0

Views: 429

Answers (3)

Ron Sims II
Ron Sims II

Reputation: 646

In you code, the this references the object returned. Therefore using this modifies the api and not myLocalObj. You might want to try something like this if you want the ability to assign the myLocalObj with something other than the empty object that is already there.

    var improvedModule = (function(){
    var myLocalObj = {};

    var api = {
        init: function(obj) {
            if (obj) {
                myLocalObj = obj;//if this is not an object the api may break doing this!!!
            }
        },
        get: function(prop) {
            if (myLocalObj[prop]) {
                return myLocalObj[prop];
            }
        },
        set: function(prop, val) {
            myLocalObj[prop] = val;
        }
    };

    return api;
})();

improvedModule.init({
    foo: true,
    bar: false
});

console.log(improvedModule.get('foo'));

Upvotes: 1

sminutoli
sminutoli

Reputation: 841

The problem is myLocalObj isn't a property of the object returned, its a local var belonging to the scope. So, you can access directly using

setObject:function(coll){
    myLocalObj = coll; // be aware! you're overriding the original {}
    myLocalObj.newProp = coll.prop // now it works as expected
}

because the closure (setObject) has access to the scope variables. You will need a getter as well to access the data from outside

getObject:function(){
    return myLocalObj;
}

Or if you need to keep safe the reference

getProp:function(prop){
    return myLocalObj[prop];
}

Hope you find it useful!

Upvotes: 3

Adrian Lynch
Adrian Lynch

Reputation: 8494

I'll explain why these lines are doing what you're seeing:

this.myLocalObj = coll; // this works just fine
this.myLocalObj.newProp = coll.prop // fails because 'myLocalObj' is undefined.

this.myLocalObj is undefined.

So undefined = 'some value' is failing silently. So "this works just fine" is not true.

this.myLocalObj.newProp is the same as undefined.newProp.

undefined has no property, newProp, hence the error.

Of course I haven't tested any of that, just winging it, like every good programmer should! :D

Upvotes: 1

Related Questions