arguments
arguments关键字,只在函数内部起作用,且永远指向当前函数的调用者传入的所有参数,类似数组而不是数组
function foo(x){ for(var i=0;i<arguments.length;i++){ console.log(arguments[i]); } } foo(10); //10 foo(10,-2,2); //10 -2 2
利用arguments,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值
function A(){
if(arguments.length ==0){
return 0;
}else{
var x = arguments[0];
return x >=0 ? x : -x;
}
}
console.log(A()); //0
console.log(A(10)); //10
console.log(A(-9,-7)); //9
实际上arguments最常用于判断传入参数的个数,由于JavaScript函数允许接收任意个参数,我们就不得不用arguments来获取所有参数。
function B(a,b){ var i,rest = []; if(arguments.length > 2){ for(i = 2 ;i<arguments.length;i++){ rest.push(arguments[i]); } } console.log('a = ' + a ); console.log('b = ' + b ); console.log(rest ); } B(1,2,3,4,5); /* a = 1 b = 2 [3,4,5]
*/ B(1); /* a = 1 b = undefined [] */
ES6标准引入了rest参数,上面的函数可以改写为
function D(a,b,...rest){
console.log('a = ' + a );
console.log('b = ' + b );
console.log(rest );
}
D(1,2,3,4,5);
/*
a = 1
b = 2
[3,4,5]
*/
D(1);
/*
a = 1
b = undefined
[]
*/
arguments是一个类数组对象,该对象还有一个callee属性,还属性是一个指针,指向拥有这个arguments对象的函数,
function a(num){ if(num <= 1){ return 1; }else{ return num * a(num -1) } } var a2 = a; a = function(){ return 0; } console.log(a(5)); //0 console.log(a2(5)); //0 function b(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num -1)
} } var c = b; b = function(){ return 0; }; console.log(c(5)); //120 console.log(b(5)); //0
在上面的递归函数a中,函数的执行与函数名紧紧耦合,一旦函数名改变,就需要及时更改函数内部,在函数b中,使用了arguments.callee,降低函数耦合性,这样,无论引用函数时使用的是什么名字,都能正常完成递归调用。
类数组转数组
因为argument是一个对象,只不过它的属性从0开始排,依次为0,1,2...最后还有callee和length属性。我们也把这样的对象称为类数组。
常见的类数组还有:
- 用getElementByTagName/ClassName/Name()获得的HTMLCollection
- 用querySlector获得的nodeList
那这导致很多数组的方法就不能用了,必要时需要我们将它们转换成数组,有哪些方法呢?