javascript caller 和 callee 的区别

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 属性要注意:属性只有当函数在执行时才有用。

参考文章:
https://www.cnblogs.com/exhuasted/p/6292688.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值