Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using slice() method on Array like Object

Tags:

javascript

I'm confused with the output.

var arrLike = {0:'Martin', 1:78, 2:67, 3:['L', 'M', 'P'], length: 4};

If I use slice() on arrLike:

var newArr = Array.prototype.slice.call(arrLike, 0);

Output:

console.log(newArr);
["Martin", 78, 67, Array[3]]

How does this happen? I can't wrap up my head around with the output.

like image 808
Bun Avatar asked Feb 08 '23 01:02

Bun


2 Answers

Preface: Note that the Array[3] in your console output is just how the console is showing it to you. Your newArr is really:

["Martin", 78, 67, ['L', 'M', 'P']]

It happens because that's how slice is defined. Loosely speaking it:

  1. Creates a new, empty array
  2. Reads the length property of what you give it
  3. Loops through from the starting index (default 0) to the ending index (default length - 1); call the loop variable k
    1. Puts any property found in the object when asking it for property k into the array at index k - start.
  4. Sets the length of the returned array to k - start.
  5. Returns the array

Or (again very loosely):

function slice(start, end) {
    var n, k, result;
    start = arguments.length < 1 ? 0 : +start;
    end = arguments.length < 2 ? +this.length : +end;
    result = [];
    for (var k = start, n = 0; k < end; ++k, ++n) {
        if (n in this) {
            result[n] = this[k];
        }
    }
    result.length = n;
    return result;
}

All the gory details.

Since your arrLike object has a length property and has properties with the names 0, 1, 2, and 3, you get the result you've shown.

like image 149
T.J. Crowder Avatar answered Feb 10 '23 23:02

T.J. Crowder


Check out the spec for slice(). The slice() function will default the end parameter, which you did not specify, to this.length, and...

  1. If end is undefined, let relativeEnd be len; else let relativeEnd be ToInteger(end).

Therefore, you're only pushing the first 4 non-element properties of the arrLike object into the new array.

Try using...

var arrLike = {0:'Martin', 1:78, 2:67, 3:['L', 'M', 'P'], length: 6, 4: 'test'};

like image 32
Eric Lease Avatar answered Feb 11 '23 01:02

Eric Lease