javascript中caller和callee详解

 更新时间:2015年08月10日 10:45:01   投稿:hebedich  
有些小伙伴可能会问caller,callee 是什么?在javascript 中有什么样的作用?那么本篇会对于此做一些基本介绍。希望能够对大家理解javascript中的callee与caller有所帮助。

最近学习javascript,碰到caller和callee的问题,去网上百度了很多。搜到的内容大同小益,整理总结了一下与大家分享。

caller:返回一个对调用function函数的函数的引用(用法:function.caller)

说明:对于函数来说,caller属性只有在函数执行时才有定义。如果函数由顶层调用,caller则为null。

var time = 3 //控制次数,去掉会一直在caller与handleCaller交替不断执行
function caller() {
  caller.caller()//返回调用caller函数的函数引用
}
function handleCaller() {
  if (time > 0){
    time--
    alert(handleCaller.caller)//返回调用handleCaller函数的函数引用
    alert(caller.caller)//返回调用caller函数的函数引用
    caller()
  }
}
handleCaller()

例子分析:第一次handleCaller运行的时候,两个alert返回的都是null,alert(handleCaller.caller)返回null是因为它是由顶层调用, alert(caller.caller)返回null是因为caller的默认值是null。接下去caller()函数被调用,caller.caller返回的是调用它的函数(handleCaller)的引用,通过caller.caller()可以再次调用handleCaller函数。第二次handleCaller运行的时候,alert(handleCaller.caller)返回的是caller代码(其实就是caller的引用),alert(caller.caller)返回的是handleCaller代码。因为函数之间的调用关系是handleCaller->caller->handleCaller。之后就不断在2个函数之间交替执行。

caller指向调用当前函数的函数,但是有一点,如果是在全局作用域内(即顶层window)被调用,则返回null。
代码走起

====================
function testCaller(){
if(testCaller.caller == null){
console.log('accessed at global');
}else{
console.log('accessed at ' + testCaller.caller);
}
}


在全局调用

testCaller(); // accessed at global

在一个函数中调用

function a(){
testCaller();
}
a(); // accessed at function a(){testCaller();} 

此时,testCaller.caller指向就是 function a

callee:返回相对应的arguments的函数引用。(多用于匿名函数递归)

说明:也许你在网上看到最多的是callee返回正在执行的函数引用。我是这么理解,每个函数都有一个自己的arguments,通常是用来存放参数的。arguments有一个callee 属性,初始值就是对应自身的函数引用。当你函数执行到该语句时,arguments是默认对应的是你现在执行的函数,那么arguments.callee为当前正在执行的函数的引用。当然如果你有标记过其他函数的arguments(例子中的args),自然可以用args.callee()去再次调用那个函数。

function a(){
  alert(arguments.callee)
  var args = arguments
  function c(){
    alert(arguments.callee)
    args.callee()
  }
  c()
}
a()

例子分析:例子中的arguments.callee都是默认返回当前正在执行的函数的引用(a中返回a自身函数引用,c中返回c自身函数引用),而通过用args存放a函数的arguments,在内置函数c中使用args.callee()再次调用a函数。

====================
function a(x){

if(x<=1)
return x;
else
return x + a(x-1);
}
a(12) // 78

这是一个极简的递归,运行结果正常。


再看看下面的调用方法

var b = a;
a = null; // 将a回收
b(12); // erro : 'a' is not a function



原因也简单,b=a,b=function a(){};在b调用之前,我们用了a=null。所以在 function a 运行的时候,其中的return x + a(x-1);中的a,指向的就是null,而不是 function a。
所以就报错了,如何解决这样的问题。我们将a换一种写法

function a(x){
if(x<=1)
return x;
else
return arguments.callee(x-1); // 这句是改变的地方
}

再调用

var b = a;
a = null;
b(12); // 78

原因:虽然我们将a=null了,但是函数a中并没有用到a,而是通过arguments.callee指向当前函数。
因为arguments.callee的定义就是:返回正在执行的函数。

相关文章

  • JS实现的贪吃蛇游戏案例详解

    JS实现的贪吃蛇游戏案例详解

    这篇文章主要介绍了JS实现的贪吃蛇游戏,结合具体案例形式分析了javascript实现贪吃蛇的相关步骤、原理、算法操作技巧与相关注意事项,需要的朋友可以参考下
    2019-05-05
  • HTML+JavaScript实现筋斗云导航栏效果

    HTML+JavaScript实现筋斗云导航栏效果

    这篇文章主要为大家介绍了如何利用HTML+JavaScript+CSS实现筋斗云导航栏效果,当鼠标经过某个li,筋斗云跟着到当前的位置,感兴趣的小伙伴可以试一试
    2022-03-03
  • JavaScript CSS 通用循环滚动条

    JavaScript CSS 通用循环滚动条

    核心是 position:relative;,才能让其内部的 ul 以绝对定位,通过改变 top 值实现向上移位置。
    2009-10-10
  • 详解JavaScript前端如何实现截屏功能

    详解JavaScript前端如何实现截屏功能

    这篇文章主要为大家详细介绍了JavaScript前端如何实现截屏功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-04-04
  • JavaScript如何利用Promise控制并发请求个数

    JavaScript如何利用Promise控制并发请求个数

    大家都知道js是单线程,并不存在真正的并发,但是由于JavaScript的Event Loop机制,使得异步函数调用有了“并发”这样的假象。这篇文章主要给大家介绍了关于JavaScript如何利用Promise控制并发请求个数的相关资料,需要的朋友可以参考下
    2021-05-05
  • js中的document.querySelector()方法举例详解

    js中的document.querySelector()方法举例详解

    这篇文章主要给大家介绍了关于js中document.querySelector()方法的相关资料,document.querySelector是JavaScript中的一个内置方法,用于通过CSS选择器选择文档中的第一个匹配元素,需要的朋友可以参考下
    2024-01-01
  • 解决前端接收 type:"application/octet-stream" 格式的数据并下载(解决后端返回不唯一问题)

    解决前端接收 type:"application/octet-stream" 格

    前端接收 type: “application/octet-stream“ 格式的数据并下载,还有后端既返回octet-stream还返回JSON数据时的处理方法,今天给大家分享前端接收 type:"application/octet-stream" 格式的数据并下载(解决后端返回不唯一问题)的解决方案,感兴趣的朋友一起看看吧
    2023-12-12
  • 使用JSX 建立 Markup 组件风格开发的示例(前端组件化)

    使用JSX 建立 Markup 组件风格开发的示例(前端组件化)

    这篇文章主要介绍了使用JSX 建立 Markup 组件风格开发的示例(前端组件化)本文重点讲解如何从0搭建一个组件系统,在这里我们会学习使用JSX来建立markup 的风格,我们基于与React 一样的 JSX 去建立我们组件的风格
    2021-04-04
  • JavaScript引用类型RegExp基本用法详解

    JavaScript引用类型RegExp基本用法详解

    这篇文章主要介绍了JavaScript引用类型RegExp基本用法,结合实例形式较为详细的分析了引用类型RegExp正则表达式相关函数使用技巧与操作注意事项,需要的朋友可以参考下
    2018-08-08
  • js实现遮罩层弹出框的方法

    js实现遮罩层弹出框的方法

    这篇文章主要介绍了js实现遮罩层弹出框的方法,可实现对遮罩层弹出框的样式定义、按钮事件及相关功能的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01

最新评论