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?
Because in order for Array.prototype.slice
to work, you need to pass an array-like object. And in order for an object to fit that category, it needs a length
property, which your object doesn't have. 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()
. To understand why it's required, imagine that you were writing your own version of Array.prototype.slice()
after reading the MDN docs:
Array.slice(begin[, end])
begin
Zero-based index at which to begin extraction.
As a negative index, begin
indicates an offset from the end of the sequence. slice(-2)
extracts the second-to-last element and the last element in the sequence.
end
Zero-based index at which to end extraction. slice
extracts up to but not including end
.
slice(1,4)
extracts the second element through the fourth element (elements indexed 1, 2, and 3).
As a negative index, end
indicates an offset from the end of the sequence. slice(2,-1)
extracts the third element through the second-to-last element in the sequence.
If end
is omitted, slice
extracts to the end of the sequence.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With