简体   繁体   English

Array.prototype.slice奇怪的行为

[英]Array.prototype.slice weird behaviour

Consider this piece of code, with console output at the end of each line: 考虑这段代码,每行末尾有控制台输出:

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)

Why is it that the third console.log outputs an empty array? 为什么第三个console.log输出一个空数组?

Because in order for Array.prototype.slice to work, you need to pass an array-like object. 因为为了使Array.prototype.slice工作,您需要传递一个类似数组的对象。 And in order for an object to fit that category, it needs a length property, which your object doesn't have. 并且为了使对象适合该类别,它需要一个length属性,而您的对象没有该属性。 Try this: 试试这个:

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);

FIDDLE 小提琴

As @basilikum described, this is because .length is required in order to use .slice() . 正如@basilikum所描述的那样,这是因为.length是为了使用.slice()所必需的。 To understand why it's required, imagine that you were writing your own version of Array.prototype.slice() after reading the MDN docs: 要理解为什么需要它,想象一下,在阅读MDN文档之后,您正在编写自己的Array.prototype.slice()版本:


Syntax 句法

Array.slice(begin[, end])

Parameters 参数

begin

Zero-based index at which to begin extraction. 从零开始的索引,开始提取。

As a negative index, begin indicates an offset from the end of the sequence. 作为负索引, begin表示从序列末尾begin的偏移量。 slice(-2) extracts the second-to-last element and the last element in the sequence. slice(-2)提取序列中倒数第二个元素和最后一个元素。

end

Zero-based index at which to end extraction. 基于零的索引,用于结束提取。 slice extracts up to but not including end . slice提取但不包括end

slice(1,4) extracts the second element through the fourth element (elements indexed 1, 2, and 3). slice(1,4)通过第四个元素(索引为1,2和3的元素slice(1,4)提取第二个元素。

As a negative index, end indicates an offset from the end of the sequence. 作为负指数, end表示距序列end的偏移量。 slice(2,-1) extracts the third element through the second-to-last element in the sequence. slice(2,-1)通过序列中倒数第二个元素提取第三个元素。

If end is omitted, slice extracts to the end of the sequence. 如果end被省略, slice提取到该序列的末端。


To handle all those cases and a few more not listed, your code would have to be something along these lines (this may have bugs but should be close): 要处理所有这些情况以及一些未列出的情况,您的代码必须是这些行(这可能有错误但应该关闭):

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;
};

That's why .slice() requires this.length —you wouldn't be able to write the function without it. 这就是为什么.slice()需要this.length - 如果没有它,你将无法编写该函数。

As much as i have knowledge 尽我所知

Argument is a variable of object type which we can use to get entry for every argument passed to a method Argument是一个对象类型的变量,我们可以使用它来获取传递给方法的每个参数的条目

for example if we use this 例如,如果我们使用它

whatever(a,b,c)

argument will return some thing like 0:a ,1:b ,2:c 参数将返回一些像0:a ,1:b ,2:c

and slice method is used to slice an array from a starting point to end point like 和slice方法用于从起点到终点切割数组

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

will return 3 and 4 as they exist on index 2 and 3 将返回3和4,因为它们存在于索引2和3上

so if u want to use slice on your arguments just define it like slice(startindex,endindex); 所以,如果你想在你的参数上使用切片,只需将它定义为slice(startindex,endindex);

just an edit slice.call is used to convert an array type to another array type data structure and in your case while passing arguments as it is a known type for javascript engine it considers it as an array type and simply converts it but hardcoding an array doesn't seems to work (just a thought). 只是一个编辑slice.call用于将数组类型转换为另一个数组类型的数据结构,在你的情况下传递参数,因为它是javascript引擎的已知类型,它认为它是一个数组类型,只是转换它但硬编码一个数组似乎没有用(只是一个想法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM