【问题标题】:Javascript Unintentionally Changing Multiple Objects' Array AttributeJavascript 无意中更改了多个对象的数组属性
【发布时间】:2018-06-29 20:43:03
【问题描述】:

我遇到了一个奇怪的问题,我试图更改特定对象中的属性值,它正在更改所有对象中的属性值。

下面是我创建这些对象“节点”的代码

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'] FOR ALL 4 OBJECTS 而不仅仅是 objectNode 变量中引用的那个。

但是,当我换行时... objectNode.fields.splice(1,1); 到... objectNode.fields = ['hi']; 那么它只会更改我引用为 var objectNode 的对象的 .fields 属性。

有人知道为什么会发生这种情况吗?我认为这可能是一个引用问题,其中所有 .fields 都在引用和更改彼此的值,但这对我来说似乎没有意义,因为当我将 .fields 属性设置为等于 ['hi'] 时,它只会更改一个对象的.fields 属性。

任何帮助将不胜感激。

【问题讨论】:

  • 如果objectNode.fields.splice(1, 1) 全部更改,那么它们确实都指向同一个数组。 objectNode.fields = ['hi'] 不会更改所有这些,因为您没有更改字段指向的数组,而是更改了特定字段指向的 what 数组。同样的方式,如果你有x = { y: [ 1 ] };,你做了x.y.push(2),那么数组将是[1, 2],或者如果你做了var y = x.y;,然后又做了y.push(2),那么数组也会变成[1, 2]。但是如果你然后做了y = [ 3, 4 ],你正在改变 y 指向的东西,而不是实际的数组

标签: javascript jquery object reference


【解决方案1】:

我在您的代码中注意到您有这一行,我想知道它是否是问题的一部分。

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

Object.create() 返回一个具有processNode 原型但不具有原型对象本身的对象。所以你有一个原型等于一个对象,里面有另一个原型。

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

这可能归因于您的参考问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    相关资源
    最近更新 更多