8

考虑这段代码,每行末尾都有控制台输出:

function whatever() {
  console.log(arguments) // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
  console.log(Array.prototype.slice.call(arguments)) // [ 1, 2, 3, 4, 5 ]
  console.log(Array.prototype.slice.call({ '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 })) // []
}

whatever(1,2,3,4,5)

为什么第三个console.log输出一个空数组?

4

3 回答 3

13

因为为了Array.prototype.slice工作,你需要传递一个类似数组的对象。为了使对象适合该类别,它需要一个length您的对象没有的属性。尝试这个:

var arr = { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 };
arr.length = 5;
var res = Array.prototype.slice.call(arr);
console.log(res);

小提琴

于 2013-07-10T06:54:11.967 回答
2

正如@basilikum 所述,这是因为.length使用.slice(). 要理解为什么需要它,假设您Array.prototype.slice()在阅读 MDN 文档后正在编写自己的版本:


句法

Array.slice(begin[, end])

参数

begin

开始提取的从零开始的索引。

作为负索引,begin表示距序列末尾的偏移量。slice(-2)提取倒数第​​二个元素和序列中的最后一个元素。

end

结束提取的从零开始的索引。slice提取最多但不包括end.

slice(1,4)从第四个元素(索引为 1、2 和 3 的元素)中提取第二个元素。

作为负索引,end表示距序列末尾的偏移量。slice(2,-1)通过序列中倒数第二个元素提取第三个元素。

如果end省略,则slice提取到序列的末尾。


要处理所有这些情况以及更多未列出的情况,您的代码必须符合以下内容(这可能有错误但应该接近):

Array.prototype.myslice = function( begin, end ) {
    // Use array length or 0 if missing
    var length = this.length || 0;
    // Handle missing begin
    if( begin === undefined ) begin = 0;
    // Handle negative begin, offset from array length
    if( begin < 0 ) begin = length + begin;
    // But make sure that didn't put it less than 0
    if( begin < 0 ) begin = 0;
    // Handle missing end or end too long
    if( end === undefined  ||  end > length ) end = length;
    // Handle negative end (don't have to worry about < 0)
    if( end < 0 ) end = length + end;
    // Now copy the elements and return resulting array
    var result = [];
    for( var i = begin;  i < end;  ++i )
        result.push( this[i] );
    return result;
};

这就是为什么.slice()需要this.length——没有它你将无法编写函数。

于 2013-07-10T08:57:55.410 回答
0

只要我有知识

参数是对象类型的变量,我们可以使用它来获取传递给方法的每个参数的条目

例如,如果我们使用这个

whatever(a,b,c)

参数将返回类似0:a ,1:b ,2:c

slice 方法用于从起点到终点对数组进行切片,例如

var myarray=["1","2","3","4"];
myarray.slice(2,3);

将返回 3 和 4,因为它们存在于索引 2 和 3 上

所以如果你想在你的参数上使用切片,只需像这样定义它slice(startindex,endindex);

只是一个编辑 slice.call 用于将数组类型转换为另一个数组类型数据结构,在您的情况下,在传递参数时,因为它是 javascript 引擎的已知类型,它认为它是一个数组类型并简单地转换它,但硬编码一个数组似乎不起作用(只是一个想法)。

于 2013-07-10T07:01:38.660 回答