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 相关文章推荐
Extjs列表详细信息窗口新建后自动加载解决方法
Apr 02 Javascript
jQuery 验证插件 Web前端设计模式(asp.net)
Oct 17 Javascript
jQuery基本过滤选择器使用介绍
Apr 18 Javascript
js如何判断不同系统的浏览器类型
Oct 28 Javascript
详解Node.Js如何处理post数据
Sep 19 Javascript
微信小程序 本地图片按照屏幕尺寸处理
Aug 04 Javascript
node.js学习之事件模块Events的使用示例
Sep 28 Javascript
JS实现判断有效的数独算法示例
Feb 25 Javascript
vue 移动端注入骨架屏的配置方法
Jun 25 Javascript
Javascript组合继承方法代码实例解析
Apr 02 Javascript
详解三种方式在React中解决绑定this的作用域问题并传参
Aug 18 Javascript
详解Anyscript开发指南绕过typescript类型检查
Sep 23 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
php4的彩蛋
2006/10/09 PHP
php木马攻击防御之道
2008/03/24 PHP
php 学习资料零碎东西
2010/12/04 PHP
关于更改Zend Studio/Eclipse代码风格主题的介绍
2013/06/23 PHP
php实现的click captcha点击验证码类实例
2014/09/23 PHP
php封装的连接Mysql类及用法分析
2015/12/10 PHP
PHP连接MSSQL方法汇总
2016/02/05 PHP
javascript 获取页面的高度及滚动条的位置的代码
2010/05/06 Javascript
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
基于jQuery实现表单提交验证
2014/11/24 Javascript
js+html5实现canvas绘制镂空字体文本的方法
2015/06/05 Javascript
jQuery实现图片上传和裁剪插件Croppie
2015/11/29 Javascript
深入分析Javascript事件代理
2016/01/30 Javascript
jQuery+formdata实现上传进度特效遇到的问题
2016/02/24 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
学习Node.js模块机制
2016/10/17 Javascript
快速将Vue项目升级到webpack3的方法步骤
2017/09/14 Javascript
聊聊JS动画库 Velocity.js的使用
2018/03/13 Javascript
js实现点击上传图片并设为模糊背景
2020/08/02 Javascript
Python 经典面试题 21 道【不可错过】
2018/09/21 Python
python matplotlib如何给图中的点加标签
2019/11/14 Python
Python concurrent.futures模块使用实例
2019/12/24 Python
Python如何重新加载模块
2020/07/29 Python
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
Html5调用手机摄像头并实现人脸识别的实现
2018/12/21 HTML / CSS
Redbubble法国:由独立艺术家设计的独特产品
2019/01/08 全球购物
欧洲最大的高尔夫零售商:American Golf
2019/09/02 全球购物
自我反省检讨书
2014/01/23 职场文书
幼教简历自我评价
2014/01/28 职场文书
学习交流会主持词
2014/04/01 职场文书
养成教育经验材料
2014/05/26 职场文书
汽车机电维修工求职信
2014/09/30 职场文书
2014年企业工会工作总结
2014/11/12 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis