arguments是一种类数组的对象,对于ES6的箭头函数不起作用
var fn = (a) => {
console.log("first:"+a)
}
var test = function (b){
console.log("second:"+b)
}
fn(1)
test(2)
在mdn上的建议是对于ES6新特性,使用剩余参数rest而不是arguments
顾名思义,虽然长得像Array但实际上用不了Array相关的方法。
因此可以用以下方法将arguments这个类数组转成数组,大体方法是:
首先将Array.prototype数组通过call或apply绑定this到arguments,再调用某个能返回整个数组的方法
例如,以下方法都可以实现这个效果:
var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
Array.prototype.join.call(arrayLike, '&'); // name&age&sex
Array.prototype.slice.call(arrayLike, 0); // ["name", "age", "sex"]
Array.prototype.map.call(arrayLike, function(item){
return item.toUpperCase();
}); // ["NAME", "AGE", "SEX"]
Array.prototype.splice.call(arrayLike, 0); // ["name", "age", "sex"]
Array.from(arrayLike); // ["name", "age", "sex"]
Array.prototype.concat.apply([], arrayLike)
大体过程讲完了,只能说懂得都懂了,接下来多写点废话,详细剖析下整个过程,将给还不懂的听听。(关于call与apply)
首先明确一点,arguments这是个类数组,也就是说他长得像,但并没有数组的功能,比如这是test函数的arguments,可以看出他原型只有Object而已
再随便var个数组,可以看到其原型有Array。
mdn上对于arguments类数组的描述
多西哟,想让argmuents使用Array的方法?那就借呗!怎么借呢?答案是使用call和apply这两个方法。
那这两个方法有什么特殊的呢?只用看一个call即可。
以下是其他博客中对于call的模拟实现,原博客地址:https://github.com/mqyqingfeng/Blog/issues/11
var foo = {
value: 1,
bar: function() {
console.log(this.value)
}
};
foo.bar(); // 1
// 第一步
foo.fn = bar
// 第二步
foo.fn()
// 第三步
delete foo.fn
可以看出,bar在call的时候把自己作为foo中的一个方法,并执行了foo.fn
同理我们可得,
// 第一步
arguments.fn = Array.prototype.slice()
// 第二步
arguments.fn()
// 第三步
delete arguments.fn
Array.prototype.slice把自己作为了arguments中的一个方法,并进行执行位于arguments中的Array.prototype.slice方法
(相当于执行了arguments.Array.prototype.slice())
再根据slice的方法,可以得出关于arguments数组对象的返回。