Array.prototype.slice weird behavior

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 does the third console.log output an empty array?

+7
javascript
source share
3 answers

Since in order for Array.prototype.slice work, you need to pass an object that looks like an array. And in order for an object to correspond to this category, it requires the length property, which your object does not have. Try the following:

 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

+12
source share

As described by @basilikum, this is because .slice() is required to use .slice() . To understand why this is required, imagine that you wrote your own version of Array.prototype.slice() after reading the MDN docs:


Syntax

 Array.slice(begin[, end]) 

Options

begin

Zero based index to start extraction.

As a negative index, begin indicates the offset from the end of the sequence. slice(-2) extracts the second-last element and the last element in the sequence.

end

Zero based index to complete extraction. slice extracts to, but not including end .

slice(1,4) retrieves the second item through the fourth item (items indexed 1, 2, and 3).

As a negative index, end indicates the offset from the end of the sequence. slice(2,-1) retrieves the third element through the second-last element in the sequence.

If end omitted, slice fetches to the end of the sequence.


To deal with all of these cases and a few others that are not listed, your code should be something like these lines (this may have errors, but it 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; }; 

This is why .slice() requires this.length - you cannot write a function without it.

+2
source share

As far as I know

An argument is an object type variable that we can use to get an entry for each argument passed to the method

for example if we use this

 whatever(a,b,c) 
Argument

returns some thing like 0:a ,1:b ,2:c

and the slice method is used to slice the array from the start point to the end point, for example

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

will return 3 and 4 since they exist on index 2 and 3

therefore, if you want to use a slice on your arguments, simply define it as slice(startindex,endindex);

just edited slice.call is used to convert the array type to another data structure of the array type, and in your case when passing arguments, since it is a known type for the javascript mechanism, it treats it as an array type and just converts it, but hardcoding array does not work (just a thought).

0
source share

All Articles