JavaScript 中 arguments 对象的特性与 callee 属性解析

作者:拾光

时间:2026-10-23

浏览:218

本文探讨 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”可能存在术语上的不严谨(标题中称其为隐含参数而非对象),但通过查看电子书原文确认,复制粘贴内容无误。


关于“对象”的讨论,对象种类繁多,后续篇章将继续探讨“对象”相关话题。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章