函数参数arguments与rest 参数解析
arguments
function add(num1, num2) {
console.log(arguments); // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7 }
}
add(1, 2, 3, 4, 5, 6, 7);
从arguments对象输出的内容我们可以看出
- arguments内部的元素,跟函数实际传入参数的数值一致
- 其index对应的数值,跟实际参数出传入的顺序也是一一对应的
- 函数每次执行有自己的arguments对象
arguments的原型指向的是Object,而array的原型指向的是Array,所以arguments严格来说不是个数组,一般我们把它称作是伪数组或者类数组。
arguments与Array的异同点
同:
- 都可通过
length获取长度 - 保存值的方式都是
index:value的形式 - 两者都可使用
for...of进行遍历
异:
- arguments是类数组,不是真的数组
- Array上的方法大多不能使用,比如:
map、forEach
arguments转为Array
方法一 自己遍历
function add(num1, num2) {
const newArr = [];
for (let i = 0; i < arguments.length; i++) {
newArr.push(arguments[i] * 10); // 遍历的时候将每个元素*10
}
console.log(newArr);
}
add(1, 2, 3, 4, 5, 6, 7);
方法二 slice
var newArr = Array.prototype.slice.call(arguments);
Array.prototype.slice的内部实现(大致):
Array.prototype.slice = function(start,end) {
// 获取到数组(包含类数组)
var arr = this;
// 不传递参数,则使用默认值
start = start || 0
end = end || arr.length
var newArr = []
for(var i = start; i < end; i++) { // 遍历数组
newArr.push(arr[i])
}
return newArr
}
方法三 ES6语法
Array.from :
var newArr = Array.from(arguments)
扩展运算符 :
var newArr = [...arguments]
箭头函数没有arguments
var foo = (num1,num2) => {
console.log(arguments);
};
foo(1,2);
箭头函数中没有arguments,那么就会向上查找:
- 在浏览器中,全局是没有
arguments变量的,所以报undefined的错误 - 在node环境中是有数据的
我们使用闭包的方法,可以在内部函数中访问外层函数的arguments
function foo (num) {
retrun () => {
console.log(arguments) // 123
}
}
var fn = foo(123)
fn()
rest 剩余参数
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
function(a, b, ...theArgs) {
// ...theArgs保存的是剩余的实参
}
剩余参数与arguments的异同
- 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
- arguments对象不是一个真正的数组,而剩余参数是真正的Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach或pop。
- arguments对象还有一些附加的属性 (如callee属性)。
- 剩余参数必须放在最后