javascript中caller和callee详解


Posted in Javascript onAugust 10, 2015

最近学习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的定义就是:返回正在执行的函数。

Javascript 相关文章推荐
Using the TextRange Object
Oct 14 Javascript
一个简单的js动画效果代码
Jul 20 Javascript
JS的replace方法详细介绍
Nov 09 Javascript
基于JS实现简单的样式切换效果代码
Sep 04 Javascript
jQuery使用cookie与json简单实现购物车功能
Apr 15 Javascript
jQuery简单实现页面元素置顶时悬浮效果示例
Aug 01 Javascript
微信小程序 canvas API详解及实例代码
Oct 08 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
Apr 23 jQuery
jQuery添加新内容的四个常用方法分析【append,prepend,after,before】
Mar 19 jQuery
laravel-admin 与 vue 结合使用实例代码详解
Jun 04 Javascript
解决 window.onload 被覆盖的问题方法
Jan 14 Javascript
JavaScript TAB栏切换效果的示例
Nov 05 Javascript
jQuery实现购物车表单自动结算效果实例
Aug 10 #Javascript
javascript中$(function() {});写与不写有哪些区别
Aug 10 #Javascript
jQuery中$(function() {});问题详解
Aug 10 #Javascript
jquery实现鼠标滑过后动态图片提示效果实例
Aug 10 #Javascript
jQuery模拟原生态App上拉刷新下拉加载更多页面及原理
Aug 10 #Javascript
jQuery 判断图片是否加载完成方法汇总
Aug 10 #Javascript
javascript实现连续赋值
Aug 10 #Javascript
You might like
虹吸壶是谁发明的?煮出来的咖啡好喝吗
2021/03/04 冲泡冲煮
PHP中的函数嵌套层数限制分析
2011/06/13 PHP
PHP命名空间(Namespace)的使用详解
2013/05/04 PHP
php中通过数组进行高效随机抽取指定条记录的算法
2013/09/09 PHP
分享五个PHP7性能优化提升技巧
2015/12/07 PHP
php变量与数组相互转换的方法(extract与compact)
2016/12/02 PHP
php提取微信账单的有效信息
2018/10/01 PHP
JS Excel读取和写入操作(模板操作)实现代码
2010/04/11 Javascript
基于JQUERY的多级联动代码
2012/01/24 Javascript
实现无刷新联动例子汇总
2015/05/20 Javascript
AngularJS Bootstrap详细介绍及实例代码
2016/07/28 Javascript
Jquery和Js获得元素标签名称的方法总结
2016/10/08 Javascript
js a标签点击事件
2017/03/30 Javascript
js实现添加删除表格(两种方法)
2017/04/27 Javascript
基于IView中on-change属性的使用详解
2018/03/15 Javascript
react redux入门示例
2018/04/19 Javascript
JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析
2019/03/06 Javascript
JavaScript监听键盘事件代码实现
2020/06/03 Javascript
[49:11]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第二场 12.20
2020/12/23 DOTA
python引用DLL文件的方法
2015/05/11 Python
Python实现股市信息下载的方法
2015/06/15 Python
利用python发送和接收邮件
2016/09/27 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
选择Python写网络爬虫的优势和理由
2019/07/07 Python
pandas按行按列遍历Dataframe的几种方式
2019/10/23 Python
tensorflow 变长序列存储实例
2020/01/20 Python
python GUI库图形界面开发之PyQt5信号与槽基本操作
2020/02/25 Python
python访问hdfs的操作
2020/06/06 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
2020/07/09 Python
群众路线教育实践活动方案
2014/02/02 职场文书
领导班子四风表现材料
2014/08/23 职场文书
网络管理员岗位职责
2015/02/12 职场文书
工程质检员岗位职责
2015/04/08 职场文书
关于JS中的作用域中的问题思考分享
2022/04/06 Javascript
Golang 字符串的常见操作
2022/04/19 Golang
使用JS前端技术实现静态图片局部流动效果
2022/08/05 Javascript