nodejs`arguments`是对象,但在浏览器中,它是一个`array`

当我从里面调用nodejs中的函数访问arguments

 echo '!function(){ console.log(arguments) }(1,2,3)' | node 

它输出一个对象…

 { '0': 1, '1': 2, '2': 3 } 

…但在谷歌铬…

 !function(){ console.log(arguments) }(1,2,3) 

输出…

 [1, 2, 3] 

为什么不一致? 还有什么其他的JS环境有不同的行为? 我可以使用arguments吗? 在使用它之前,如何确保它始终是一个数组?

控制台输出没有规则。 输出不代表任何与语言标准有关的事情。

如果你创build一个loggingJS程序中的值的程序,你可以自由地显示你想要的值。

arguments对象在两个地方都是一样的。 只是它如何显示是不同的。

在使用它之前,如何确保它始终是一个数组?

这不是一个数组。 它总是一个类似数组的对象。 在这两种情况下,它显示对象成员02 。 只是使用不同的显示语法来做到这一点。

在Chrome中,尝试创build一个像这样的对象:

 var my_obj = { "0": 1, "2": 3, "1": 2, length: 3, splice: function(){}, }; 

并将其logging在控制台中。 它可能看起来像一个数组文字,但显然不是。

它也不是浏览器中的数组arguments对象实际上在JavaScript中比Array有更长的时间,而当数组第一次被添加到JavaScript(早在1.1天)时,它们并没有将arguments更新为Array。 自那时起,他们还没有做过,因为担心向后兼容。 它显示在一些浏览器控制台,就好像它是一个数组,因为debugging控制台知道,大多数人打算把它作为一个无论如何

但是arguments对象足够接近一个数组,它很容易转换 。 一种方法是这样的:

 var args = Array.prototype.slice.call(arguments, 0); 

Array.prototype.slice与大多数Array.prototype的方法一样,被写成通用的: 您可以在不是数组的对象上调用它,只要它们具有带数字名称和length属性的属性数量,它会工作arguments对象有这两个东西,所以这些函数将在它上面工作。

slice函数返回一个数组,它是传递给它的任何对象的浅表副本,以您指定的任何数字开始和结束。 我们告诉它从零开始,因为我们没有说停止,它假设我们希望它停止在最后 ,无论它在哪里。 这样,我们将arguments所有元素都复制到一个新的数组中,现在您可以使用任何其他数组来做任何事情。