callee和caller

callee和caller在之前的文章中我说到了 arguments 现在来说一下他的属性 callee 和一个长得相似的双胞胎弟弟 caller 首先说 callee 来一段代码 vara function console log arguments callee varb function a b 这段代码在 chrom

在之前的文章中我说到了arguments,现在来说一下他的属性callee和一个长得相似的双胞胎弟弟caller:

首先说callee,来一段代码:

 var a=function(){ console.log(arguments.callee); } var b=function(){ a() } b();

这段代码在chrome中输出的是:

ƒ (){ console.log(arguments.callee); }

这个函数和a函数是不是一模一样?

callee返回正在执行的函数本身的引用。callee是arguments的一个属性,这个属性是一个指针,指向这个拥有arguments对象的函数,arguments是调用函数,那么这个callee就是调用函数的啦)
首先我们来说一个用callee解决的例子,阶乘的计算:
 function factorial(num){ if(num<=1){ }else{ return num*factorial(num-1); } }

上面的代码是用的是函数名。上述方法会增强耦合性,为了降低耦合性我们就用callee,而且无论引用函数的时候是什么名字都可以完成递归调用。看看callee:

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


caller:和他相似的我们还有一个caller,es5中规范化了另外一个函数对象属性caller这个属性中保存着调用当前的函数的函数引用,如果是全局作用于中调用当前的函数就返回null  
function outer(){ inner(); } function inner(){ 1. alert(arguments.callee.caller); 2. alert(inner.caller) //上面的这两行是一样的1比2 的耦合性更松散 3. alert(arguments.caller);//undefined // 3.这行代码在严格模式下会报错,但是非严格模式下就是undefined } outer(); // 说是定义argumnets.callee属性是为了分清qrguments.caller和caller // 属性严格模式下不能为caller属性赋值,不然报错
 // var a=function(){ // alert(a.caller); // }//定义一个函数。里面输出a.caller // var b=function(){ // a(); // }//定义一个函数调用那个a函数; // b();//输出b函数。
上面的例子中,是调用的b根据caller的特性就知道了答案。
 // var a=function(){ // alert(a.caller); // }//定义一个函数。里面输出a.caller // var b=function(){ // a(); // }//定义一个函数调用那个a函数; // a();//null(a在任何函数中被调用,即为顶层函数,输出的就是null),上面的例子一中,a函数是在b中调用的所以不是顶层不反悔null,返回当前的调用就是b函数啦,而这个例子是在全局中调用的自然是null


最后一个例子帮助深刻地理解顶层:要是a中也有了一个函数

var c=function(){ alert(c.caller); } var a=function(){ c() alert(a.caller); } var b=function(){ a(); } a();

这个例子在c中的alert出来的是a函数,原因是在a中调用。

a中alert出来的是null,毕竟你是在全局中调用的a的函数。b函数相当于没有用。
好了,这么多例子都不懂的话,可能是我写的太差吧。


 


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

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

(0)
上一篇 2026年3月26日 下午1:54
下一篇 2026年3月26日 下午1:54


相关推荐

  • js中数组常用遍历,VUE 中数组常用遍历

    js中数组常用遍历,VUE 中数组常用遍历VUE 中常用 for 循环

    2026年3月26日
    3
  • java把string转换为int_java如何把String类型转换为int类型

    java把string转换为int_java如何把String类型转换为int类型在 java 中 实现 String 类型转换为 int 类型的方法有 Integer parseInt String 方法 Integer valueOf String 方法 本篇文章就给大家介绍 java 把 String 类型转换为 int 类型的两种方法 让大家了解 String 类型如何可以转换为 int 类型 希望对你们有所帮助 1 Integer parseInt String 方法 parseInt 是 Integ

    2026年3月17日
    2
  • sort()与拉姆达表达式

    sort()与拉姆达表达式sort 与拉姆达表达式的结合 include iostream include string include vector include ctime include map include utility include algorithm usingstd algorithm utility map ctime vector string iostream

    2026年3月17日
    1
  • 腾讯群关系数据泄漏下载什么软件_云和数据/和华为之间的关系

    腾讯群关系数据泄漏下载什么软件_云和数据/和华为之间的关系腾讯群关系数据泄漏(可根据QQ号获得该人姓名经历等详细信息),外界已经有下载地址了,迅雷上就可以看到很多用户数据泄漏,可能是早期的漏洞被利用抓取的,可以根据QQ查一个人的姓名,年龄,关系网甚至从业经历等等

    2026年4月16日
    5
  • verilog流水线设计代码_流水线cpu设计verilog

    verilog流水线设计代码_流水线cpu设计verilog介绍定义:流水线设计就是将组合逻辑分割,并在各级之间插入寄存器,暂存中间数据的方法。以面积换速度。优点:每一部分延时降低——可用更快的时钟;大部分电路同时运算——提高数据吞吐率。缺点:增加面积;流水线并不减小单个数据操作的时间,减小的是整个数据流的操作时间;(不懂)功耗增加,硬件复杂度增加,特别对于复杂逻辑如cpu的流水线而言,流水越深,发生需要hold流水线或reset流水线的情况时,时间损失越大。所以使用流水线并非有利无害,大家需权衡考虑。应用场景:1)组合逻辑太长,

    2022年8月14日
    5
  • java中如何获取当前系统时间[通俗易懂]

    java中如何获取当前系统时间[通俗易懂]java.util包中提供的和日期时间相关的类有Date类、Calendar类和SimpleDateFormat类等。方法一:Date类对象用来表示日期和时间,该类提供了一系列操作日期和时间各组成部分的方法,Date类中使用最多的是获取系统当前的日期和时间,如Datedate=newDate();这句代码是使用当前时间创建日期对象示例代码如下:publicstaticvoidm…

    2022年10月19日
    6

发表回复

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

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