【问题标题】:Javascript associative array: pushing an object rewrites other array elementsJavascript关联数组:推送一个对象会重写其他数组元素
【发布时间】:2014-11-07 20:39:08
【问题描述】:

我有一个描述我的文档的对象。每个文档都包含层,这些层在数组中的对象中进行了描述

var example = {
    id: 'some_id',
    layers: [{
        id: 'some_layer_id',
        width: 100,
        height: 200
    }]
};

有不同类型的图层,每个都有它的模板:

var layer_templates = [{
    type: 'text',
    width: 100,
    height: 100,
    style: 'common'
}];

我在 jQuery 事件中创建新图层:

jQuery('#button').on('click', function () {
    var ldata = layer_templates[0]; // get a template
    ldata['id'] = 's-l-' + Math.random().toString(); // create an id
    example['layers'].push(ldata); // add new "layer" to document
    console.log(example['layers']); // check
});

每次我将新的ldata 层添加到example['layers'] 数组时,它只保留带有id: 'some_layer_id' 的初始对象,并用最后一个对象重写所有新创建的对象。

请查看 jsFiddle:Problem in action

【问题讨论】:

  • 这是一个控制台问题并设置了相同的 id。登录console.log(ldata.id);JSON.stringify(ldata);
  • 同样的事情发生在 IE 中。主要问题是我尝试更新一个更大的数组,它用相同 ids 的对象更新它((
  • 所有的控制台都这样做...你只记录了 id 吗?会被骗吗?
  • 不,只是 id 不会欺骗

标签: javascript jquery arrays associative-array


【解决方案1】:

问题在于您没有复制模板。您在所有图层中使用和重复使用相同的模板

var ldata = layer_templates[0];
ldata['id'] = 's-l-' + Math.random().toString(); // create an id

实际上,ldata 只是一个引用模板的指针,向其添加 id 值只会修改您的模板,因此现在看起来像这样:

var layer_templates = [{
    type: 'text',
    width: 100,
    height: 100,
    style: 'common',
    id: 's-l-0.08636776800267398'
}];

下次您尝试添加另一个图层时,您再次执行相同的操作,这只会再次拉动和更改模板......最后,每个图层都引用相同的模板,因此是完全相同的数据。

要解决此问题,您需要复制模板,其中一种方法是使用 JSON:

var ldata = JSON.parse(JSON.stringify(layer_templates[0]));

此方法创建一个全新的 ldata 对象,它是模板的副本。

【讨论】:

  • 谢谢!我认为我不必创建新副本,因为我每次都更改 id...
猜你喜欢
  • 1970-01-01
  • 2019-12-22
  • 2016-07-03
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 2020-08-23
相关资源
最近更新 更多