2014-07-15 24 views
1

我发现了一个行为,当尝试使用循环来改变对象中属性的值时,我并没有想到。如何更新循环内的对象属性?

基本上,我声明我的对象在循环之外。 然后我循环一个数值的数组,这些数值用于更新对象属性。 在循环内部,我将当前对象状态存储在外部数组中。

结果是,不是让一个数组包含一系列具有不同数值的对象,而是最终在每个存储的对象中都有相同的数值。

这里是小提琴http://jsfiddle.net/fAypL/1/

jQuery(function(){ 

    var object_container = []; 

    var numeric_values = [1, 2 , 3, 4]; 

    var my_object = {}; 


    jQuery.each(numeric_values, function(index, value){ 
     my_object['value'] = value; 
     object_container.push(my_object); 
    }); 

    jQuery.each(object_container, function(index, value){ 
     jQuery('#content').prepend(value['value']); 
    }); 

}); 

我希望得到1 2 3 4为存储在每个对象的值,但是,我得到的是4 4 4 4,这没有任何意义对我来说。

这种行为任何暗示是更受欢迎,感谢

回答

5

当代码调用.push()并传递my_object,什么东西被传递是参考对象。没有复制。

因此,您已将四个引用推送到完全相同的对象到数组中。

JavaScript对象总是以引用的形式参与表达式。没有其他方式来处理对象。因此,当您创建一个变量并将其值设置为一个对象时,您确实将其值设置为对该对象的引用。与参数传递一样,以及对象可以出现在表达式中的任何地方。

在这种情况下,您可以非常轻松地创建新对象;只是my_object分配和推每次迭代新鲜:

object_container.push({ value: value }); 
+2

正确的,并且以固定,创建一个新的'my_object'每次迭代在'推'之前。 – rvighne

2

你周围循环每次不创建一个新的对象 - 你是刚刚更新同现有对象和推动的引用对象数组。创建要像做一个新的对象:

my_object = { 'value': value }; 
object_container.push(my_object); 

在这种情况下,你现在会得到更多的东西像你所期待的。看到更新的小提琴在这里:http://jsfiddle.net/fAypL/2/

祝你好运!

还有一个想法(克隆!) - 如果您真的被绑定到每次使用相同的对象,只需克隆该对象,然后再添加到数组中。 that here有一个很好的解决方案。

0

您正在使用jQuery的,所以如果你想要的是不影响在原来的样子合并:

var both_obj = $.extend({}, default_obj , adding_obj); 

这将使您的原始对象改变了,也很好用的copy

jquery docs - extend()

0

另一种版本是使用具有一个构造方法的对象和所述关键字new

var object_container = []; 
var numeric_values = [1, 2 , 3, 4]; 

function MyObject(value) 
{ 
    this.value = value; 
} 


jQuery.each(numeric_values, function(index, value){  
    object_container.push(new MyObject(value)); 
}); 

jQuery.each(object_container, function(index, value){ 
    jQuery('#content').prepend(value['value']); 
}); 

Fiddle