JavaScript 中 arguments 对象的特性与 callee 属性解析
本文探讨 JavaScript 函数中隐含的 arguments 对象。通过代码示例分析其长度特性,并验证其并非 Array 实例。重点解析 arguments.callee 属性在匿名函数递归中的应用,对比传统递归写法,解释其封装性优势,并澄清 arguments 作为类数组对象的本质。
JavaScript arguments 对象的基本特性
初次接触这个概念时,容易将其误解为一种无需在函数定义中显式声明的普通参数。
正如那句名言所言,代码成本极低,直接通过代码验证更为直观。
function funcTest(a, b) {
alert(a);
alert(b);
for ( var i = 0 ; i < arguments.length; i ++ ) {
alert(arguments[i]);
}
}
function test() {
funcTest( 1 , 2 , 3 ); // 放到html页进行执行
}
function funcTest(a, b) {
alert(a);
alert(b);
for ( var i = 0 ; i < arguments.length; i ++ ) {
alert(arguments[i]);
}
}
function test() {
funcTest( 1 , 2 , 3 ); // 放到html页进行执行
}
执行上述代码后,输出结果依次为:1、2、1、2、3。这表明即使函数定义时未指定参数列表,仍可通过 arguments 访问传入的所有参数,从而赋予编程极大的灵活性。
验证 arguments 并非 Array 实例
具备一定 JavaScript 基础的开发人员可能会产生疑问:arguments 是否为 Array 对象的实例?以下代码用于验证这一假设。
Array.prototype.testArg = " test arguments " ;
function funcArg() {
alert(arguments.testArg);
}
function test() {
alert( new Array().testArg);
funcArg();
}
Array.prototype.testArg = " test arguments " ;
function funcArg() {
alert(arguments.testArg);
}
function test() {
alert( new Array().testArg);
funcArg();
}
代码执行结果首先弹出 "test arguments",随后弹出 "undefined"。funcArg 内部返回 undefined 的原因在于 arguments 并非真正的数组实例,因此无法继承 Array.prototype 上自定义的属性。这澄清了 arguments 并非 Array 实例的疑问。
若认为已完全掌握 arguments 的所有特性,则可能低估了 JavaScript 设计者的巧思。接下来探讨另一个关键设计。
利用 arguments.callee 实现递归
Q:使用递归来计算 1 到 n 的自然数之和
A1:
function sum(n) {
if ( 1 == n) return 1 ;
else return n + sum(n - 1 );
}
function test() {
alert(sum( 100 )); ; // 放到html页进行执行
} function sum(n) {
if ( 1 == n) return 1 ;
else return n + sum(n - 1 );
}
function test() {
alert(sum( 100 )); ; // 放到html页进行执行
}
A2:
function sum(n) {
if ( 1 == n) return 1 ;
else return n + arguments.callee(n - 1 );
}
function test() {
alert(sum( 100 )); ; // 放到html页进行执行
} function sum(n) {
if ( 1 == n) return 1 ;
else return n + arguments.callee(n - 1 );
}
function test() {
alert(sum( 100 )); ; // 放到html页进行执行
}
A1 和 A2 两种方案均能解决问题。A1 是常见的常规做法,但 JavaScript 更推荐 A2 方式。原书指出,A1 方式中函数内部直接调用自身名称 sum,而在 JavaScript 中函数名仅是一个变量名,在函数内部调用 sum 相当于调用全局变量,未能很好地体现“调用自身”的语义。既然 sum 调用了 sum,为何还说“不能很好地体现出是调用自身”?
arguments.callee 的封装性与争议
查阅资料可知,arguments 对象的另一个重要属性是 callee,它指向函数对象本身。这一设计有利于实现无名函数的递归或确保函数的封装性。尽管书中表述“arguments 对象的另一个属性是 callee”可能存在术语上的不严谨(标题中称其为隐含参数而非对象),但通过查看电子书原文确认,复制粘贴内容无误。
关于“对象”的讨论,对象种类繁多,后续篇章将继续探讨“对象”相关话题。
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
