类似数组虽然有length属性,可以使用for循环遍历,却不能直接使用slice方法,会报错!但是通过Array.prototype.slice.call则不会报错,本身(类似数组)被从头到尾slice复制了一遍——变成了真实数组,为什么”类似数组不能直接slice, 而借助Array.prototype可以slice”?
为什么”类似数组不能直接slice
slice本就是数组自带的方法,非“真”数组没有这方法,所以
arguments.slice 报错
Array.prototype.slice 正确
而借助Array.prototype可以slice”?
更准确说,是类数组(array-like)对象通过.call方法借用Array.prototype上的slice方法(自己若没有这方法,就只能依靠借用别人的)
强烈推荐看下知识点
1.slice
2.call
类似数组的对象没有slice方法吧
因为 slice
是 Array
原型链上的方法
为什么”类似数组不能直接slice
Flyn 已经回答。因为类数组对象并不是真正的数组,所以不能直接调用数组的 slice 方法。
而借助Array.prototype可以slice”?
通过查看MDN 上介绍的 slice 方法的 profill 函数中可以看出:
// 节选其中的一些片段
Array.prototype.slice = function (begin, end) {
// some code
end = (type end !== 'undefined') ? end : this.length
// some code
var start = begin || 0
// some code
var clones = []
if (size > 0) {
cloned = new Array(size);
if (this.charAt) {
for (i = 0; i < size; i++) {
cloned[i] = this.charAt(start + i)
}
} else {
for (i = 0; i < size; i++) {
cloned[i] = this[start + i]
}
}
}
return cloned
}
调用 slice 方法时,如果不传值的话,start 和 end 的值会是 0 和 length,然后进行遍历生成新的数组并返回。
因为类数组不是真正的数组,他没有从Array
的prototype
上继承到slice
方法。
ES6 Array.from
Array.prototype.slice.call(this,arguments),相当于当前上下文调用了数组的slice方法。