caller
caller 返回一个函数的引用,这个函数调用了当前的函数。
通俗的说法就是:caller 返回调用当前函数的函数。
function judgeType(){
console.log(judgeType.caller);
}
function test(){
judgeType();
}
test();
运行结果:
ƒ test(){
judgeType();
}
test() 调用了 judgeType(),所以 judgeType.caller 返回的是 test()。
如果是由顶层调用这个函数,返回null:
var a = function() {
console.log(a.caller);
}
a();
运行结果:
null
以利用 caller的特性跟踪函数的调用链:
function test() {
let call = test.caller;
console.log(call);
}
function test1() {
test();
}
function test2() {
test1();
}
function test3() {
test2();
}
function test4() {
test3();
}
test4();
运行结果:
ƒ test1() {
test();
}
callee
callee 返回正在执行的函数本身的引用,它是arguments 的一个属性。
function judgeType(){
console.log(arguments.callee);
}
function test(){
judgeType();
}
test();
运行结果:
ƒ judgeType(){
console.log(arguments.callee);
}
callee 使用注意事项:
(1)有一个length属性,可以用来获得形参的个数,因此可以用来比较形参和实参个数是否一致,即比较arguments.length是否等于arguments.callee.length。
获取形参的个数,例子:
function judgeType(){
console.log(arguments.callee.length);
}
function test(){
judgeType();
}
test();
运行结果:
0
function judgeType(a,b,c){
console.log(arguments.callee.length);
}
function test(){
let num1=1;
let num2 = 2;
let num3 = 3;
judgeType(num1,num2,num3);
}
test();
运行结果:
3
判断实参的个数是否等于形参的个数,例子:
function judgeType(a,b,c){
console.log("形参长度: ",arguments.callee.length);
console.log("实参长度:",arguments.length);
console.log(arguments.length === arguments.callee.length);
}
function test(){
let num1=1;
let num2 = 2;
let num3 = 3;
judgeType(num1,num2,num3);
}
test();
运行结果:
形参长度: 3
实参长度: 3
true
function judgeType(a,b){
console.log("形参长度: ",arguments.callee.length);
console.log("实参长度:",arguments.length);
console.log(arguments.length === arguments.callee.length);
}
function test(){
let num1=1;
let num2 = 2;
let num3 = 3;
judgeType(num1,num2,num3);
}
test();
运行结果:
形参长度: 2
实参长度: 3
false
(2)callee 通常用于递归函数
function test(num) {
if( num == 1 ) {
return 1;
}
let res = num * test(num-1)
console.log(res)
return res
}
test(100);
例如上面的例子,用到了递归,但是如果我们改变函数名称,则也要同时改变函数体中的名称,想要函数体不依赖于函数名称,可以用 arguments.callee 来实现:
function test(num) {
if( num == 1 ) {
return 1;
}
let res = num * arguments.callee(num-1)
console.log(res)
return res
}
test(100);
使用 caller 和 callee 属性要注意:属性只有当函数在执行时才有用。