javascript jQuery push() 到数组的奇怪行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23974383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:55:04  来源:igfitidea点击:

Strange behavior for jQuery push() into array

javascriptjqueryarrays

提问by rosuandreimihai

I'm trying to push some elements into a 2d array The code I am using is:

我正在尝试将一些元素推入二维数组我使用的代码是:

samount.push ({
        "value": val, 
        "currency": currency
    });

The array that I am trying to push into samount is like this:

我试图推入 samount 的数组是这样的:

groupedArray = 
     [{value: 100, currency: 'EUR'},
      {value: 100, currency: 'EUR'},
      {value: 100, currencu: 'EUR'}]

In fact, the array above represents rows of one table, and at each row click, the push() function is adding do samount array a new element

其实上面的数组代表一个表的行,每点击一行,push()函数就是给do samount数组添加一个新元素

After 2 row clicks, the samount array looks like:

单击 2 行后,smount 数组如下所示:

samount = 
     [{value: 100, currency: 'EUR'},
      {value: 100, currency: 'EUR'}]

At the third row click, the array becomes:

在第三行单击时,数组变为:

samount = 
     [{value: 200, currency: 'EUR'},
      {value: 100, currency: 'EUR'},
      {value: 100, currencu: 'EUR'}]

I have to mention that my code has no sum inside, so it is very strange that the push() function is summing the values of first element and still is adding them to the array

我不得不提一下,我的代码里面没有 sum,所以很奇怪 push() 函数正在对第一个元素的值求和并且仍然将它们添加到数组中

Do you know if the push() function is ok for adding element to this type of arrays?

你知道 push() 函数是否可以向这种类型的数组添加元素?

The complete code is:

完整的代码是:

"fnDrawCallback": function (oSettings) {  
    var $dt = $('#dt_debts').footable({  
     breakpoints: { // The different screen resolution breakpoints  
         phone: 320,  
         tablet: 768  
     }   
    });  
    $dt.trigger('footable_resize');  

    var amount      = new Array();
    var samount     = new Array();  

    $('#dt_debts tbody tr ').each( function () {                            
        var iPos = oTable.fnGetPosition( this );
        if (iPos!=null) {
            var aData = oTable.fnGetData( iPos );
            if (jQuery.inArray(aData[0], selected)!=-1) {
                $(this).addClass('row_selected');
                $(this).find( 'td input:checkbox' ).attr('checked', 'checked');
            }
        }
        $(this).click( function (e) {   
            e.preventDefault();                     
            var iPos = oTable.fnGetPosition( this );
            var aData = oTable.fnGetData( iPos );
            var iId = aData[0];
            is_in_array = jQuery.inArray(iId, selected);
            if (is_in_array==-1) {
                selected[selected.length]=iId;
            }
            else {
                selected = jQuery.grep(selected, function(value) {
                    return value != iId;
                });
            }
            if ( $(this).hasClass('row_selected') ) {
                console.info('>>> Operatie de eliminare');
                $(this).removeClass('row_selected');
                $(this).find( 'td input:checkbox' ).prop('checked', false);
                if ($(aData[0]).data('typo') == "t-0") {
                    val = parseFloat(aData[9].split(" ")[0]);
                    currency = aData[9].split(" ")[1];
                    if (currency != '') {
                        $.each(amount, function(idx, item) {
                            if (item.currency == currency && item.value == val) {
                                amount.splice(idx, 1); // Remove current item
                                return false; // End the loop
                            }
                        });
                    }
                } else if ($(aData[0]).data('typo') == "t-1") {
                    val = parseFloat(aData[10].split(" ")[0]);
                    currency = aData[10].split(" ")[1];
                    if (currency != '') {
                        $.each(samount, function(idx, item) {
                            if (item.currency == currency && item.value == val) {
                                samount.splice(idx, 1); // Remove current item
                                return false; // End the loop
                            }
                        });                                 
                    }                                       
                }
                console.info(amount);
                console.info(samount);
            } else {
                console.info('>>> Operatie de adaugare');
                $(this).addClass('row_selected');                                   
                $(this).find( 'td input:checkbox' ).attr('checked', 'checked');

                if ($(aData[0]).data('typo') == "t-0") {
                    val = parseFloat(aData[9].split(" ")[0]);
                    currency = aData[9].split(" ")[1];
                    if (currency != '') {
                        amount.push ({
                                "value": val, 
                                "currency": currency
                            });
                    }       
                } else if ($(aData[0]).data('typo') == "t-1") {
                    val = parseFloat(aData[10].split(" ")[0]);
                    currency = aData[10].split(" ")[1];
                    if (currency != '') {
                        samount.push ({
                                "value": val, 
                                "currency": currency
                            });
                    }       
                }
                console.info(amount);
                console.info(samount);                                  
            }
}

Aftre spending hours of searching the error, I have figured that the error is in this part of code:

在花费数小时搜索错误之后,我发现错误出在这部分代码中:

var objects1 = new Array();
objects1 = samount;
var categories1 = new Array();
var groupedObjects1 = [];
var i = 0;

_.each(objects1,function(obj){
    var existingObj;

    if($.inArray(obj.currency,categories1) >= 0) {
        existingObj = _.find(objects1,function(o){return o.currency === obj.currency;});
        existingObj.value += obj.value;
    } else {
        groupedObjects1[i] = obj;
        categories1[i] = obj.currency;
        i++;
    }
});// JavaScript Document

Actually it seems that the samountarray is beeing modified even if I have declared a new array for using into loop. I do not understand why the loop is modifying the initial array, even if I am not using it

实际上,即使我已经声明了一个用于使用 into 循环的新数组,似乎也正在修改samount数组。我不明白为什么循环会修改初始数组,即使我没有使用它

回答by VLAZ

Yes, push is fine. Indeed I tested it and it works as it is supposed to. What I assume is happening is the value being modified somewhere else - since you are pushing an object into the array with the value valthe array would only hold a reference to the entire thing notthe values it represents.

是的,推就好了。事实上,我测试了它,它按预期工作。我假设正在发生的是在其他地方修改的值 - 因为您将一个对象推入数组,该数组的值val将只保存对整个事物的引用,而不是它所代表的值。

Just to illustrate this

只是为了说明这一点

var val = { "value" : 100 };
var storage = [ ];

storage.push(val);


console.log("value  : " + val.value);
console.log("value in storage : " + storage[0]["value"]);

val.value = 200;

console.log("value  : " + val.value);
console.log("value in storage : " + storage[0]["value"])

yields

产量

value  : 100
value in storage : 100
value  : 200
value in storage : 200

The variables in JavaScript are pass by value for primitives (e.g., integers) but pass by reference for objects.

JavaScript 中的变量对于基元(例如,整数)是按值传递的,但对于对象是按引用传递的。

回答by Janaka R Rajapaksha

You can use .join()instead of .push()

您可以使用.join()代替.push()

 //if you want the ful array as a single element:
    groupedArray = 
         [{{value: 100, currency: 'EUR'},
          {value: 100, currency: 'EUR'},
          {value: 100, currencu: 'EUR'}}];

    samount.join(groupedArray);


//if you want each element in groupedArray as elements in samount:
groupedArray = 
     [{value: 100, currency: 'EUR'},
      {value: 100, currency: 'EUR'},
      {value: 100, currencu: 'EUR'}];

samount.join(groupedArray);