arguments
arguments对象是所有(非箭头)函数中都可用的局部变量,此对象包含传递给函数的每个参数。arguments类似Array,但不是一个Array实例,除了length属性和索引元素之外没有任何Array属性。
arguments对象的长度由实参(实际调用的参数)而不是形参(正式声明接受的参数)决定。形参是函数内部重新开辟内存空间存储的变量,其与arguments对象内存空间不重叠。在arguments和形参都存在的情况下,两者值是同步的,如果其中一个无值,对该值的修改将不会同步。
function fun (a, b, c) {
console.log(arguments.length); // "2"
a = 100;
console.log(arguments[0]); // "100"
arguments[0] = "3";
console.log(a); // "3"
console.log(c); // "undefined"
c = 2012;
console.log(arguments[2]); // "undefined"
}
fun(1, 2);
callee
callee是arguments对象的一个属性。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时可以使用arguments.callee代替函数名本身。
// 阶乘函数
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1)
}
}
// 使用arguments.callee替换factorial
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
与函数名 factorial解耦之后不管引用函数时使用的是什么名字,都可以保证正常完成递归调用。
注意:在严格模式下,第5版 ECMAScript (ES5) 禁止使用 arguments.callee()。当一个函数必须调用自身的时候, 避免使用 arguments.callee(), 通过要么给函数表达式一个名字,要么使用一个函数声明。
caller
caller这个属性保存着调用当前函数的函数作用域,本属性已被移除且不再有用,可以使用 Function.caller。
function whoCalled() {
console.log(whoCalled.caller);
if (arguments.caller == null) console.log('该函数在全局作用域内被调用.');
else console.log(arguments.caller + '调用了我!');
}
function a() {
whoCalled();
};
a()