Javascript, непреднамеренно изменяющий атрибут массива нескольких объектов - PullRequest
0 голосов
/ 29 июня 2018

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

Ниже мой код создает эти объекты "узлы"

function processNode(nodeID, name, fields){
    this.id =  nodeID;
    this.fields = fields;
    this.name = name;
}

var nodeFuncs = {table:
    function(nodeID){
        function tableNode() {}
        tableNode.prototype = Object.create(new terminalNode(nodeID, 'table'));
        return new tableNode(nodeID, 'table');
    }
    , source:
    function(nodeID){
        function sourceNode() {}
        sourceNode.prototype = Object.create(new processNode(nodeID, 'source'));
        sourceNode.prototype.table = '';
        sourceNode.prototype.selectors = '';
        sourceNode.prototype.include = 1;

        return new sourceNode(nodeID, 'source', []);
    }
    , sort:
    function(nodeID){
        function sortNode() {}
        sortNode.prototype = Object.create(new processNode(nodeID, 'sort'));
        sortNode.prototype.order = [];

        return new sortNode(nodeID, 'sort', [])
    }
    , filter:
    function(nodeID){
        function filterNode() {}
        filterNode.prototype = Object.create(new processNode(nodeID, 'filter'));
        filterNode.prototype.names = [];

        return new filterNode(nodeID, 'filter', [])
    }
}

function createNode(nodeID, name){
    return nodeFuncs[name](nodeID);
}

idToNodeObjectMap['abc123'] = createNode('abc123', 'source')
idToNodeObjectMap['abc124'] = createNode('abc124', 'sort')
idToNodeObjectMap['abc125'] = createNode('abc125', 'filter')
idToNodeObjectMap['abc126'] = createNode('abc126', 'filter')

Вот пример события jquery, которое запускает переоценку атрибута объекта:

$('body').on('click', "div button.ok", function(){
    var nodeID = $(this).parent('div.nodeForm').attr('id')
    var objectNode = idToNodeObjectMap[nodeID];
    objectNode.fields.splice(1,1);
});

Например, у меня будет 4 объекта, и я буду ссылаться на один из них как var objectNode со значением .fields ['tid', 'gid', 'tname']. Затем, когда я вызываю objectNode.fields.splice (1,1), значением .fields будет ['tid', 'tname'] ДЛЯ ВСЕХ 4 ОБЪЕКТОВ, а не только тот, который является ссылкой в ​​переменной objectNode.

НО, когда я меняю строку ... objectNode.fields.splice (1,1); чтобы ... objectNode.fields = ['hi']; тогда он только изменяет атрибут .fields объекта, на который я ссылался как var objectNode.

Кто-нибудь знает, почему это произойдет? Я подумал, что это может быть проблема со ссылками, когда все .fields ссылаются и изменяют значения друг друга, но это, кажется, не имеет смысла для меня, потому что когда я устанавливаю атрибут .fields равным ['hi'], он изменяет только один объект Атрибут .fields.

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 30 июня 2018

Я заметил в вашем коде, что у вас есть эта строка, и мне интересно, является ли это частью проблемы.

filterNode.prototype = Object.create(new processNode(nodeID, 'filter'));

Object.create () возвращает объект, имеющий прототип processNode, но не сам объект-прототип. Таким образом, у вас есть прототип, равный объекту с другим прототипом внутри него.

filterNode {
    __proto__: processNode {
        __proto__: processNode.prototype
    }
}

Возможно, это связано с вашими ссылочными проблемами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...