Связанные объекты? - PullRequest
0 голосов
/ 25 января 2012

Я испытываю некоторые действительно странные поведения объекта в данный момент. У меня есть этот шаблон объекта:

template: {
        trigger: {
            width: 32,
            height: 32,
            delay: 0
        },

        player: {
            direction: {
                value: "right",
                options: "left|right"
            }
        },

        apple: {
            direction: {
                value: "down",
                options: "up|down|left|right"
            }
        }
},

, который является объектом объекта с именем layers. Внутри функции в объекте layers я добавляю новые данные (сущности) в пустой объект entities.

if (!this.entities[which])
{ this.entities[which] = []; }

if (!this.entities[which][id])
{ this.entities[which][id] = {}; }

this.entities[which][id].pos = "0,0";
this.entities[which][id].variables = {};
this.entities[which][id].variables = this.template[which];

Поэтому позже, когда я пытаюсь изменить, например, this.entities[which][id].variables.width, каждое право, владеющее тем же шаблоном для which, получает те же свойства, что и объект шаблона, который не будет изменен нигде в коде. хоть. Я отладил почти все и прошел через каждый бит кода. Идентификаторы прав также уникальны.

Часть, где объект изменяется, выглядит так: input.setAttribute("onkeyup", "layers.entities['" + i + "'][" + j + "].variables['" + jj + "'] = this.value; layers.updateEntities();");

Где i - название права, j - идентификатор, а jj - имя опции.

Вы можете попробовать это для себя прямо здесь: [Удалено]

Переключитесь на слой сущностей, добавьте два триггера, перетащите один из них, щелкните его правой кнопкой мыши и измените одно из свойств. Оба будут меняться, хотя у них разные идентификаторы. Также новые будут иметь эти свойства.

Поскольку сам шаблон изменился, я подумал, что этот this.entities[which][id].variables = this.template[which]; каким-то образом связывает эти два объекта вместо назначения «копии» левой переменной. Хотя я никогда не слышал ничего подобного.

1 Ответ

1 голос
/ 26 января 2012

Объекты в Javascript передаются по ссылке, поэтому вы правы, подозревая, что проблема заключается в том, что все используют один и тот же набор переменных:

var a = {x:1};
var b = a;
b.x = 2;
console.log(a.x); //gives 2

Существует множество способов исправить ваш код, но очень простой.будет иметь шаблоны как функции конструктора вместо непосредственного возврата объекта

template: {
    trigger: function(){
        //now we return a brand new object each time.
        return {
            width: 32,
            height: 32,
            delay: 0
        };
    },
    player: function(){ /*...*/},
    apple: function(){ /*...*/}
}

//...

this.entities[which][id].variables = this.template[which]();
                                                       //^^^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...