2

我一直在對對象文字等進行一些研究。我正在製作一款遊戲,其中包含來自我的玩家的各種屬性。這些prorpeties被存儲在多個組中,比如他的船和所有的屬性,他的wepaon以及所有的屬性等。因此,我一直在將這些屬性存儲到對象文字中。保護對象文字並防止被覆蓋的良好做法

我不希望我的對象值被覆蓋。我碰到這裏的一篇文章http://www.gabordemooij.com/jsoop.html跑,和好奇,如果是這樣,這將是一個健康的開始,從容易被覆蓋保持對象的值...

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! 
+2

看看這個參考[揭示對象模式](http://stackoverflow.com/questions/5647258/how-to-use-revealing-module-pattern-in-javascript)。這是你在這裏試圖做的更平滑的變化。 –

+0

可以顯示對象模式返回本地對象字面值嗎? – blackhawk

回答

1

我已經建立了在jsFiddle一個小的測試證明顯露的對象模式是一個多麼美妙的事情:

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) 
+0

太棒了!謝謝Shmiddty!但是無論如何,我們可以做同樣的事情,但是沒有每次創建「新」實例? – blackhawk

+0

@blachawk那種失敗的目的不是嗎?當然,你可能有一個「玩家」,但是遊戲中的其他物體呢?子彈,敵人等你需要單獨的實例嗎? – Shmiddty

+0

ahhh - 你讓我現在思考。我可以稱它爲演員,然後爲每種類型的演員創建​​一個新實例!謝謝! – blackhawk

0

它失敗,因爲聲音是不能被引用的局部變量對象之外。

如果你想引用它,你需要做一個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()); 

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")); 
+0

在第一個示例中,如果聲音是具有多個本質值的對象字面值,然後返回,那麼這是否是健康的練習?如果是這樣,我會製作多個代表我的玩家屬性的var對象並返回每個對象。請讓我知道,如果這聽起來愚蠢 - 第一次學習這個東西。 – blackhawk