为什么数组上的.toString会产生奇怪的结果?

时间:2014-07-26 03:20:09

标签: javascript arrays object

我知道这个问题反映了我无法完全理解JS中对象和数组之间的差异,以及何时最好同时使用它们。我想了解为什么以下函数的输出是如此疯狂,希望这将有助于我理解JS中的Objs和数组的一些细节。

//orders is an array of numbers
function myFunction(orders, callback){  
 var sold = []; //fixed by changing to an obj
 var open = []; //fixed by changing to an obj
 var reply = [];
 var response = function(sold, open){ 
     reply.push({Output: {sold:sold, open:open}});
     callback(reply);
  };
  orders.forEach(function(id, i){
    //somelogic that builds sold and open
    if(i == orders.length -1) response(sold, open);
  });
 }

在此示例中,sold和open都是键值数组。 response的输出符合我的预期:

[ { Output: { sold: [Object], open: [Object] } } ]

但是,如果我只是通过向任一阵列添加.toString()来稍微修改它,我会得到一个巨大的波浪输出,最终导致我不得不硬杀死这个过程。解决方案很明显,我需要传入对象而不是数组,并使用JSON.strigify()。我的问题是为什么这些结果如此截然不同?意外输出是否使用带有键值数组的.push?我已成功使用数组作为键值对,但我是否应该更改对象的回复并删除push方法?

1 个答案:

答案 0 :(得分:1)

了解一个"键值数组"非常重要。在Javascript中,根据定义意味着你正在谈论一个对象。因为对象是键值,而数组是索引值。

您的代码有点难以阅读,因为我不知道您给出的输入或您期望的输出。但是,如果我理解正确,您希望返回一个具有两个属性的对象:soldopen,因此您可以将其称为reply.soldreply.open。这意味着reply应该是一个对象,有两个键:"出售"和"打开"。这两个键的两个值都是包含订单的数组。这些不需要是一个对象,因为不需要密钥。

您实际上可以在一行中定义对象reply和两个数组reply.soldreply.open

var reply = { sold: [], open: [] }

表示您的响应函数如下所示:

var response = function(sold, open){ 
    reply.sold.push(sold);
    reply.open.push(open);
    callback(reply);
};

最后,这将是reply

的结构
{
    sold: [ order1, order2, order3, ... ],
    open: [ orderA, orderB, orderC, ... ]
}

由于reply.soldreply.open现在是数组,您只需使用.join(glue)将它们转换为更易读的字符串:

var soldString = reply.sold.join(", ") // "order1, order2, order3, ..."
var openString = reply.open.join(", ") // "orderA, orderB, orderC, ..."

在这种情况下使用数组的另一个有用的事情是,你实际上可以给订单一个特定的订单(没有双关语意)。对于对象,大多数Javascript引擎在执行" for"时会按字母顺序运行属性。环。但是,这不是保证。但是在数组上调用.forEach()时,或者在执行常规for循环时。

//  assuming object "obj", and array "arr"
for(var key in obj) { /* order of "key" is not guarantied */ }
for(var i = 0; i < arr.length - 1; i ++) { /* "i" is always in ascending order */ }

希望这有点帮助。