js 类数组arguments详解

时间:2022-05-06 11:36:33

arguments并不是一个真正的数组,而是一个“类似数组(array-like)”的对象;

就像下面的这段输出,就是典型的类数组对象:

[, , callee: ƒ, Symbol(Symbol.iterator): ƒ]

一、类数组 VS 数组

相同点:

  • 都可用下标访问每个元素
  • 都有length属性

不同点:

  • 数组对象的类型是Array,类数组对象的类型是Object;
  • 类数组对象不能直接调用数组API;
  • 数组遍历可以用for in和for循环,类数组只能用for循环遍历;
function calc(){
console.log(arguments); // ["sky", "moon", callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(arguments[]); // sky
console.log(arguments.length); // 2
// arguments.pop(); // 报错,arguments.pop is not a function
} calc('sky', 'moon');

类数组对象转为数组对象方法: Array.prototype.slice.call ( arguments );

function calc(){
var newArr = Array.prototype.slice.call(arguments);
newArr.pop();
console.log(newArr); // ["sky"]
} calc('sky', 'moon');

二、类数组的用法

1、实现重载(overload):当函数的参数个数不明确时,函数体根据参数的不同进行相应处理;

比如我们要实现:一个参数时,做乘法运算;二个参数时,做加法运算;

看下面代码,我们可以这样实现:

// 实现重载(overload)
function calc(){
//传1个参数,求平方
if(arguments.length == ){
return arguments[] * arguments[];
}
//传2个参数,求和
else if(arguments.length == ){
return arguments[] + arguments[];
}
}
console.log(calc());//
console.log(calc(,));//

2、实现递归:在函数内部反复的调用函数本身

首先我们用最原始的方法,实现数字的叠加

function calc(num){
if(num <= ){
return ;
}else{
return num += calc(num - );
}
} console.log(calc()); //

然后我们用类数组来实现同样的功能:

arguments.callee:返回当前函数本身
function calc(num){
if(num <= ){
return ;
}else{
return num += arguments.callee(num - );
}
}
console.log(calc()); //

下面举个栗子,来说明这两种调用的一点小区别:

如果写成 return num += calc(num - 1) 会报错;原因很简单,当执行calc = null 后,calc已经不是一个函数;

但是写成 return num += arguments.callee(num - 1) 不会报错;因为arguments.callee指的是“当前函数”,并不是“calc”

function calc(num){
console.log(arguments);
if(num <= ){
return ;
}else{
return num += arguments.callee(num - );
// return num += calc(num - 1); // 报错 Uncaught TypeError: calc is not a function
}
}
var result = calc;
calc = null;
console.log(result());

注意: arguments.callee的用法在严格模式下是不允许的;

Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

"use strict";
function calc(num){
if(num <= ){
return ;
}else{
return num += arguments.callee(num - );
}
}
console.log(calc());