jQuery数据方法将数据推送到子对象

时间:2013-11-18 03:37:35

标签: javascript jquery

使用jQuery的.data()函数看到非常奇怪的行为。当我为父元素赋值时,它的子元素也会被赋予该数据值。

HTML:

<div id="parent" class="things" data-tallest="[]">
  <div id="child1" class="things" data-tallest="[]">
    I'm a child
  </div>
  <div id="child2" class="things" data-tallest="[]">
    I'm another child
  </div>
</div>

JS:

somearray = ["child1", "child2"]
$(".things").data("tallest",[])
for (var i = 0; i < somearray.length; i++) {
  tocheck = somearray[i]
  newarray = $("#"+tocheck).parent().data("tallest")
  newarray.push(20);
  $(tocheck).parent().data("tallest",newarray)
}

console.log("Correct: parent 'tallest': "+$("#parent").data("tallest"));
console.log("Problem: child1 'tallest': "+$("#child1").data("tallest"));

看到这个小提琴(在控制台日志中注明了问题):

http://jsfiddle.net/cTY3H/5/

应该发生什么:

  1. 清除存储在任何对象的数据最高变量中的所有值
  2. 循环遍历数组并将“20”推送到父对象$("#parent")数据最高数组
  3. $("#parent").data("tallest")应该等于[20,20] - 确实如此。
  4. 但是,$("#child1").data("tallest") == [20,20]
  5. 儿童对象在任何时候都没有分配到.data(“最高”),所以我不知道为什么会这样。
  6. 我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

初始化所有。things项,以对同一个空数组具有完全相同的引用。所以,当你修改一个时,它们都会改变,因为它们都指向同一个数组。记住,数组是通过引用分配和检索的。所以,这一行:

$(".things").data("tallest",[])

为每个.things对象分配对完全相同的数组的引用。改变一个,它们都会改变,这解释了你的输出。


你可以修复它并简化它:

// initialize all things to have their own empty array for data
$(".things").each(function() {
    $(this).data("tallest", []);
});
["#child1", "#child2"].each(function() {
    // get reference to parent data array and push a value onto it
    $(this).parent().data("tallest").push(20);
    // you don't have to set it back because the array is by reference so already changed
});

在操作数组时,您还必须非常小心,因为数组是通过引用传递的。因此,当您从一个地方获取数据并修改它时,您正在修改原始数据,因为获取数组没有复制,它只是有一个引用。我不认为你在这里咬你,但如果你试图从一个元素中获取数据,修改它并将其分配给另一个元素,那么很容易就可以了。

答案 1 :(得分:2)

问题出在这里:

$(".things").data("tallest",[])

您将相同的数组放入每个元素的数据中。因此,通过原型继承,它们都共享对同一数组的引用。

更改为:

$(".things").each(function(){
    $(this).data("tallest",[])
})

每个人都拥有自己独特的数组

DEMO

简单对象参考示例:

var a=[];
var b=a;
b.push('foo');
alert(a[0]); //foo