我知道这个问题反射(reflect)了我未能完全理解 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 方法?
最佳答案
重要的是要了解 Javascript 中的“键值数组”的定义意味着您在谈论一个对象。因为对象是key-value,数组是index-value。
您的代码有点难以阅读,因为我不知道您提供的输入或期望的输出。但是如果我理解正确的话,你想返回一个有两个属性的对象:sold
和 open
,所以你可以将它称为 reply.sold
和 reply.open
。这意味着 reply
应该是一个对象,有两个键:“sold”和“open”。这两个键的两个值都是包含订单的数组。这些不需要是对象,因为不需要键。
你实际上可以在一行中定义对象reply
,以及两个数组reply.sold
和reply.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.sold
和 reply.open
现在是数组,您可以简单地使用 .join(glue)
将它们转换为更具可读性的字符串:
var soldString = reply.sold.join(", ") // "order1, order2, order3, ..."
var openString = reply.open.join(", ") // "orderA, orderB, orderC, ..."
在这种情况下使用数组的另一个有用的事情是您实际上可以给订单一个特定的顺序(没有双关语意)。对于对象,大多数 Javascript 引擎在执行“for in”循环时将按字母顺序运行属性。但是,这不能保证。但是在数组上调用 .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 */ }
希望对您有所帮助。
关于javascript - 为什么数组上的 .toString 会给出奇怪的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24967190/