修改对象会导致修改反映在先前推送到数组的该对象的副本中

时间:2017-11-07 16:27:15

标签: javascript object

我的代码类似于以下

var l_mattes_array = [];
var matte_array = [];
var mattes = [];
mattes[0] = "<test><imgsrc>test1</imgsrc></test>";
mattes[1] = "<test><imgsrc>test2</imgsrc></test>";
$(mattes).each(function(i, el)
{
  matte_array.imgsrc = ($(el).find("imgsrc").first().text());
  l_mattes_array[i] = matte_array;
  console.log(l_mattes_array[i]);
});
console.log(l_mattes_array);

我得到的输出是:

[imgsrc: "test1"]
[imgsrc: "test2"]

(2) [Array(0), Array(0)]
0:[imgsrc: "test2"]
1:[imgsrc: "test2"]

我想要的输出:     [imgsrc:&#34; test1&#34;]     [imgsrc:&#34; test2&#34;]

(2) [Array(0), Array(0)]
0:[imgsrc: "test1"]
1:[imgsrc: "test2"]

4 个答案:

答案 0 :(得分:2)

问题是matte_array是一个引用类型(所有对象都是,而数组是对象,所以是的)。这意味着,当你说l_matte_array[i] = matte_array时,你实际上是将l_matte_array的索引设置为对数组matte_array的值的引用,然后当你修改matte_array时在第二次迭代中,您正在修改matte_array引用的值,该值与您在前一次迭代中设置l_matte_array[i]的值相同。

因此,您的所有l_matte_array索引仅仅包含对单个共享值的引用,并且您已修改该值以使其imgsrc属性等于"test2"

去阅读this MDN文章,您将对它有很好的理解JavaScript数据类型。


您的代码的另一个问题是,您使用数组作为对象,这是不合适的。如果要利用其具有数字索引元素的功能,请使用数组;如果你想在某个地方组合一些属性和/或方法,只需使用普通对象(用文字创建:var obj = {});如果你想要一些东西来保存一个值,请使用一个变量。

所以,我通过以下方式解决了你的问题(我没有使用imgsrc的变量,因为我相信你以后会在某个时候修改持有imgsrc的对象代码,如果您没有向推送到l_mattes_array的对象添加任何属性/方法,只需用imgsrc变量替换我的对象):

var l_mattes_array = [];
    var mattes = [];

    mattes[0] = "<test><imgsrc>test1</imgsrc></test>";
    mattes[1] = "<test><imgsrc>test2</imgsrc></test>";

    $(mattes).each(function(i, el) {
      var matte_object = {};
      matte_object.imgsrc = ($(el).find("imgsrc").first().text());
      l_mattes_array[i] = matte_object;
    });

    console.log(l_mattes_array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

答案 1 :(得分:0)

您可以使用Array.prototype.map()并使用正则表达式/<{1}[^<>]{1,}>{1}/g删除所有html标记。

代码:

const mattes = ['<test><imgsrc>test1</imgsrc></test>', '<test><imgsrc>test2</imgsrc></test>'];
const l_mattes_array = mattes.map(el => ({imgsrc: el.replace(/<{1}[^<>]{1,}>{1}/g, '')}));

console.log(l_mattes_array);

答案 2 :(得分:0)

问题是您引用了同一个对象(matte_array),因此您正在更改src属性,但引用仍然相同。你可以做的只是在循环中初始化matte_array,所以每次它成为一个新的数组,如下所示:

// ...
// var matte_array = []; // Should not be here
// ...
$(mattes).each(function(i, el)
{
  var matte_array = []; // Should be here
  // ...
});
// ...

这里有一个有效的例子:https://jsfiddle.net/6j73wgdw/

答案 3 :(得分:-1)

我添加了

matte_array = [];

添加到l_mattes_array并修复后