区分callee和caller

区分callee和callercallee 和 caller 是对象的两个属性 今天就来区分一下这两个 callee 是 arguments 对象的一个属性 指向 arguments 对象的函数 即当前函数 caller 是函数对象的一个属性 指向调用当前函数的函数体引用 用处 1 递归我们可能用到一些函数调用自身 即递归 平时我们计算阶乘是用下述方法 functionfact x ret

callee和caller是对象的两个属性,今天就来区分一下这两个:

callee是arguments对象的一个属性,指向 arguments 对象的函数,即当前函数。
caller是函数对象的一个属性,指向调用当前函数的函数体引用。





用处

1、递归
我们可能用到一些函数调用自身,即递归。平时我们计算阶乘是用下述方法:

function factorial(x) { 
      return x<=1 ? 1 : x*factorial(x-1); }

运行后发现它很好的完成了我们的要求。可是还是存在一个问题,万一哪天有人重构这个函数改了函数名呢?修改不方便甚至漏改。

arguments.callee

使用callee 避免hard code 函数名。

function factorial(num) { 
      return num<=1 ? 1 : num * arguments.callee(num-1); }

callee是arguments对象的一个属性,指向 arguments 对象的函数,即当前函数。在例子中是factorial(num)。

caller

函数对象的一个属性,指向调用当前函数的函数。比如 A() 调用 B(), 则在B()中 B.caller 指向A()。

function B(){ 
      console.log(B.caller); } (function A(){ 
      B() })()

显然,只有当函数被调用时,该属性才会有值。不过当函数被全局调用时,该属性为null。

callee和caller结合

我们刚才在函数B() 中使用了 B.caller 。跟上面递归一样,将来如果有人重构改了函数名呢? 下面用刚才说的 arguments.callee 替换。

function A(){ 
      B(); } function B(){ 
      console.log(arguments.callee.caller); //事项更松散的耦合,访问同样的信息 } A();

到这是不是好多了。再执行A() ,发现跟刚才的输出一样。

但是在严格模式下运行时,访问arguments.callee会导致错误,在非严格模式下始终是undefined。定义这个属性是为了分清arguments.caller和函数的caller属性。还有一个限制是不能为函数的caller属性赋值,否则会导致错误。

2、斐波那契数列

function fib(nMonth){ 
      return nMonth<=2 ? 1 : arguments.callee(nMonth -1) + arguments.callee(nMonth - 2) } console.log(fib(10))
function fib(nMonth){ 
      var tempResult = []; if(nMonth<=2){ return 1; } else { if(tempResult[nMonth] > 0) { return tempResult[nMonth]; } else { tempResult[nMonth] = arguments.callee(nMonth -1) + arguments.callee(nMonth - 2); return tempResult[nMonth]; } } } // 递归是从大往小分解问题,循环则是反方向算法。

3、箭头函数
我们知道 ES6 新特性中引入了箭头函数。比如:

var sum = (num1, num2) => num1 + num2; // 等同于 var sum2 = function(num1, num2) { 
      return num1 + num2; }; // 验证 console.assert(sum(1, 2) == 3)

现在问题来了,箭头函数中this作用域跟函数外是一致的,且没有 arguments 对象。而上面我们都是从 arguments 中获取 callee 的。因此在箭头函数中,上述使用是失效的。

var sum3 = () => console.log(arguments); // Uncaught ReferenceError: arguments is not defined



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214308.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午4:34
下一篇 2026年3月18日 下午4:34


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号