来自MDN对arguments的解释:
- arguments 是一个对应于传递给函数的参数的类数组对象。
- arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数
function foo(num1, num2, num3) {
// 类数组对象中(长的像是一个数组, 本质上是一个对象): arguments
console.log(arguments) // 1,2,3
}
foo(1,2,3)
常见的对arguments的操作
- arguments.length : 得到本次函数调用时传入函数的实参数量。
arguments.length 表示的是实际上向函数传入了多少个参数,这个数字可以比形参数量大,也可以比形参数量小 (形参数量的值可以通过Function.length获取到).
function foo(num1, num2) {
console.log(arguments.length) // 3
}
foo(1,2,3)
- arguments[number] :根据索引值获取某一个参数
function foo(num1, num2) {
console.log(arguments[2]) // 3
}
foo(1,2,3)
- arguments.callee :获取当前arguments所在的函数
callee 是 arguments 对象的一个属性。它可以用于引用该函数的函数体内当前正在执行的函数。这在函数的名称是未知时很有用,例如在没有名称的函数表达式 (也称为“匿名函数”) 内。
function foo(num1, num2) {
console.log(arguments.callee)
}
foo(1,2,3)
🚨警告: 在 严格模式下,第 5 版 ECMAScript ( ES5) 禁止使用 arguments.callee()。当一个函数必须调用自身的时候,避免使用 arguments.callee(),通过要么给函数表达式一个名字,要么使用一个函数声明。
因为arguments是类数组,它没有 Array的 内置方法, 例如 forEach() 和 map()都是没有的。
所以要将arguments转成array来使用
将arguments转成array的方法
- 自己遍历元素然后加进新的数组里面
function foo(num1, num2) {
var newArr = []
for (var i = 0; i < arguments.length; i++) {
newArr.push(arguments[i] * 10)
}
console.log(newArr)
}
foo(1,2,3)
- Array.prototype.slice 或是[ ]将arguments转成array
function foo(num1, num2) {
var newArr2 = Array.prototype.slice.call(arguments)
console.log(newArr2)
var newArr3 = [].slice.call(arguments)
console.log(newArr3)
}
foo(1,2,3)
🚨 警告: 对参数使用 slice 会阻止某些 JavaScript 引擎中的优化,所以为了提高性能,不推荐使用 slice 来进行数组转换
- ES6 的语法
function foo(num1, num2) {
var newArr4 = Array.from(arguments)
console.log(newArr4)
var newArr5 = [...arguments]
console.log(newArr5)
}
foo(1,2,3)
箭头函数没有arguments
因为箭头函数中没有arguments,如果在箭头函数中输入console.log(arguments)
,它会去上层函数去找,如果有则输出,没有则报错
🤔如果我们传的实参比形参多,并想要拿到这些额外的参数,该怎么办?
可以使用剩余参数
var foo = (num1, num2, ...args) => {
console.log(args)
}
foo(1,2,3,4,5)
备注: 如果你编写兼容 ES6 的代码,那么优先推荐使用 剩余参数
剩余参数和arguments对象的区别
- 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
// 剩余函数
function foo(num1, num2, ...args) {
console.log(args)
}
foo(1,2,3,4,5)
// arguments
function foo(num) {
console.log(arguments)
}
foo(1,2,3,4,5)
- arguments对象不是一个真正的数组,而剩余参数是真正的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如forEach 等
- arguments对象还有一些附加的属性 (如callee属性)。