In addition to normal usage, slice is often used to convert array-like objects into true arrays.
Noun explanation: array-like object – an object with a length attribute, such as { 0: 'foo', length: 1 } , or even { length: 'bar' }. The most common array-like objects are arguments and NodeList.
Looking at the source code of V8 engine array.js, the internal implementation of slice can be simplified to:
function slice(start, end) {
var len = ToUint32( this.length), result = [];
for(var i = start; i < end; i ) {
result.push(this[i]);
}
return result ;
}
It can be seen that slice does not need this to be an array type, it only needs to have a length attribute. And the length attribute does not need to be of type number. When it cannot be converted to a numeric value, ToUnit32(this.length) returns 0.
For standard browsers, the principle of slice has been clearly explained above. But the annoying ie always causes us trouble:
var slice = Array.prototype.slice;
slice.call(); // => IE: Object expected.
slice.call(document.childNodes); // => IE: JScript object expected .
The above code reports an error in IE. It’s a shame that IE’s Trident engine is not open source, so we can only guess:
function ie_slice(start, end) {
var len = ToUint32(this.length), result = [];
if(__typeof__ this !== 'JScript Object') throw 'JScript object expected';
if(this === null) throw 'Oject expected';
for(var i = start; i < end; i ) {
result.push(this[ i]);
}
return result;
}
At this point, the wretched ie is justified.
Regarding slices, there is another topic: Should I use Array.prototype.slice or [].slice? Theoretically, [] needs to create an array, and the performance will be slightly worse than Array.prototype. But in fact, the two are almost the same, just like whether to use i or i in a loop, it is purely a matter of personal habit.
The last topic is about performance. For array filtering, there is a way to write at the expense of hue:
var ret = [];
for(var i = start, j = 0; i < end; i ) {
ret[j ] = arr[i];
}
Exchange space for time. Remove push, and the performance improvement is quite obvious for large arrays.
Writing a blog early in the morning, I am not in a good mood, so I have to leave a topic for everyone:
var slice = Array.prototype.slice;
alert(slice.call({0: 'foo', length: 'bar'})[0]); / / ?
alert(slice.call(NaN).length); // ?
alert(slice.call({0: 'foo', length: '100'})[0]); // ?