2

I've been doing some research on object literals and such. I am creating a game that has various properties from my player. These prorpeties are stored in multiple groups, such as his ship and all the properties for that, his wepaon and all the properties for that, etc..As a result I have been storing these properties into object literals.

I don't want my object values to be overwritten. I ran across an article here http://www.gabordemooij.com/jsoop.html, and curious if something like this would be a healthy start to keeping object values from easily being overwritten...

Cat = {
  createNew: function() {
    var cat = {};
    var sound = "meow"; //sound is local
    cat.makeSound= function(){
        //can reach sound from here
        alert( sound );
    }
    return cat;
  }
}

var cat = Cat.createNew();
cat.makeSound();
//but can't reach sound from here
alert(cat.sound); //fail!
Niko
  • 26,516
  • 9
  • 93
  • 110
klewis
  • 7,459
  • 15
  • 58
  • 102
  • 2
    Check out this reference to the [Revealing Object Pattern](http://stackoverflow.com/questions/5647258/how-to-use-revealing-module-pattern-in-javascript). It is a smoother variation of what you are trying to do here. – Jeremy J Starcher Sep 28 '12 at 21:16
  • can the revealing object pattern return local object literal values? – klewis Sep 28 '12 at 21:44

2 Answers2

1

It fails because sound is a local variable which can not be referenced outside of the object.

If you want to reference it, you need to make a getter.

Cat = {
  createNew: function() {
    var cat = {};
    var sound = "meow"; //sound is local
    cat.getSound= function(){
        //can reach sound from here
        return sound;
    }
    return cat;
  }
}


var cat = Cat.createNew();
alert(cat.getSound());

or

Cat = {
  createNew: function() {
    var cat = {};

    var props = {
        sound : "meow",
        foo : "bar"
    };

    cat.get= function(key){            
        return props[key];
    }
    return cat;
  }
}

var cat = Cat.createNew();
alert(cat.get("sound"));
epascarello
  • 204,599
  • 20
  • 195
  • 236
  • In your first example, if sound was an object literal with multiple properity values, that was then returned, is that healthy practice? If so I would make multiple var objects that represent various properties of my player and return each object. Please let me know if this sounds dumb - learning this stuff for the first time. – klewis Sep 28 '12 at 21:41
1

I've set up a small test in jsFiddle to demonstrate how the Revealing Object Pattern is a wonderful thing:

var Test = (function(){
    var priv = "Banana";
    var public = "Orange";
    var pubobj = {name:"Cheese"};

    function constructor(){
        this.public = public;
        this.pubobj = pubobj;

        this.instance = {name:"Grape"};

        this.instanceMethod = function(){
            return priv;
        };
    };

    constructor.prototype.private = function(){
        return priv;
    };            

    return constructor;

})();

var myTest = new Test();

console.log(myTest.public);     //Orange
console.log(myTest.priv);       //undefined
console.log(myTest.private());  //Banana

var myTest2 = new Test();

console.log(myTest.public === myTest2.public);    //true (they are both primitives with the same value)
console.log(myTest.private === myTest2.private);  //true (the methods share the same instance)

myTest.public = "cheese";
console.log(myTest.public, myTest2.public);       // "cheese", "Orange" (overwriting the primitive doesn't change the primitive of myTest2)

myTest.pubobj.name = "Melon";                   
console.log(myTest.pubobj, myTest2.pubobj);       //the name property for both is now "Melon" (both test objects share the same instance of pubobj)

myTest.instance.name = "Raspberry";
console.log(myTest.instance, myTest2.instance);  // the name of myTest2.instance is unchanged

console.log(myTest.instanceMethod === myTest2.instanceMethod);​  // false (while identical, these methods have separate instances)
Shmiddty
  • 13,847
  • 1
  • 35
  • 52
  • That is awesome! and thank you Shmiddty! but is there anyway we can do the same thing you have just done but without creating a "new" instance every time? – klewis Sep 28 '12 at 21:50
  • @blachawk That sort of defeats the purpose doesn't it? Sure, you may have one "Player", but what about other objects in the game? Bullets, enemies, etc. You'll want separate instances right? – Shmiddty Sep 28 '12 at 21:54
  • ahhh - you got me thinking now. i can call it actors, and then creating a new instance for each type of actor! thank you! – klewis Sep 28 '12 at 21:57
  • And remember, you can modify the `constructor` method (or whatever you want to call it) to take parameters, and store those as instance parameters. – Shmiddty Sep 28 '12 at 22:00