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 of array type, it only needs to have the 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]); // ?