对 Array.prototype.slice.call(arguments,1) 的简要理解。
首先对其进行简要拆分:
- Array.prototype 属性表示 Array 构造函数的原型,并允许您向所有Array对象添加新的属性和方法。
- slice(start,end) 是Array原型上的方法,可以对一个数组进行截取(从start开始,不包含end;如果只有 start 则截取从 start 到数组结束的所有元素。)并返回一个新的数组(浅拷贝)。
- call() 简单理解为可以改变对象的this指向,与此类似的还有apply()。apply()和call()方法的第一个参数都是特定的作用域,不同之处是apply()第二个参数可以是数组实例或arguments类数组对象,call()需要逐个列出需要传递的参数。
Array.prototype.slice.call(arguments,1) 可以理解为:改变数组slice方法的作用域,使 this 指向arguments对象,call() 方法的第二个参数表示传递给slice的参数即截取数组的起始位置。这样 arguments 类数组就可以使用数组的方法 slice() 了,否则由于 arguments 是类数组并不是真正的数组,他是不可以使用 Array 的相关方法的。
简单理解为: Array.prototype.slice.call(arguments,1) 能够将具有length属性(这一点需要注意,必须包含length属性)的对象转换为数组,简化记忆为:arguments.toArray().slice(1); 但有一个例外,IE下的节点集合它不能转换(因为IE下的dom对象是以com对象的形式实现,js对象和com对象不能进行转换)。
//arguments
function fn(){
console.log(Array.prototype.slice.call(arguments,1));//["e"]
console.log(arguments.slice(1))//报错
}
fn(1,'e')
//有length属性的对象,键名不能改(不懂)
let obj = {0:'h',1:'i',length:2};
console.log(Array.prototype.slice.call(obj,0));//["h", "i"]
//没有length属性的对象
let obj2 = {0:'h',1:'i'};//没有length属性
console.log(Array.prototype.slice.call(obj2,0));//[]