Хорошая практика для защиты объектных литералов и предотвращения их перезаписи [закрыто]


Я занимался некоторыми исследованиями объектных литералов и тому подобного. Я создаю игру, которая имеет различные свойства от моего игрока. Эти prorpeties хранятся в нескольких группах, таких как его корабль и все свойства для этого, его wepaon и все свойства для этого, etc..As в результате я хранил эти свойства в объектных литералах.

Я не хочу, чтобы мои значения объектов были перезаписаны. Я наткнулся здесь на статью 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 2

2 ответа:

Я установил небольшой тест в 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)

Это не удается, потому что звук является локальной переменной, на которую нельзя ссылаться вне объекта.

Если вы хотите ссылаться на него, вам нужно сделать геттер.

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