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 相关文章推荐
取得父标签
Nov 14 Javascript
javascript:;与javascript:void(0)使用介绍
Jun 05 Javascript
JavaScript关闭当前页面(窗口)不带任何提示
Mar 26 Javascript
window.location 对象所包含的属性
Oct 10 Javascript
基于jQuery实现文本框缩放以及上下移动功能
Nov 24 Javascript
JavaScript插件化开发教程 (一)
Jan 27 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
Sep 23 Javascript
如何实现json数据可视化详解
Nov 24 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
Oct 26 Javascript
vue 进阶之实现父子组件间的传值
Apr 26 Javascript
微信小程序搭建自己的Https服务器
May 02 Javascript
JavaScript 实现下雪特效的示例代码
Sep 09 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
火车采集器 免费版使出收费版本功能实现原理
2009/09/17 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
PHP自定义序列化接口Serializable用法分析
2017/12/29 PHP
js 限制数字 js限制输入实现代码
2012/12/04 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
动态的绑定事件addEventListener方法的使用
2014/01/24 Javascript
移动设备web开发首选框架:zeptojs介绍
2015/01/29 Javascript
JS实现不使用图片仿Windows右键菜单效果代码
2015/10/22 Javascript
JS数组排序方法实例分析
2016/12/16 Javascript
Javascript下拉刷新的简单实现
2017/02/14 Javascript
JavaScript自定义文本框光标
2017/03/05 Javascript
基于BootStrap multiselect.js实现的下拉框联动效果
2017/07/28 Javascript
vue多种弹框的弹出形式的示例代码
2017/09/18 Javascript
angular 实现同步验证器跨字段验证的方法
2019/04/11 Javascript
vue源码nextTick使用及原理解析
2019/08/13 Javascript
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
Python中编写ORM框架的入门指引
2015/04/29 Python
python 处理dataframe中的时间字段方法
2018/04/10 Python
python使用selenium登录QQ邮箱(附带滑动解锁)
2019/01/23 Python
Pytorch中accuracy和loss的计算知识点总结
2019/09/10 Python
基于python实现把图片转换成素描
2019/11/13 Python
基于Python获取城市近7天天气预报
2019/11/26 Python
python如何获取apk的packagename和activity
2020/01/10 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
python 使用三引号时容易犯的小错误
2020/10/21 Python
Python系统公网私网流量监控实现流程
2020/11/23 Python
CSS3混合模式mix-blend-mode/background-blend-mode简介
2018/03/15 HTML / CSS
KARATOV珠宝在线商店:俄罗斯珠宝品牌
2019/03/13 全球购物
以实惠的价格轻松租车,免费取消:Easyrentcars
2019/07/16 全球购物
幼教毕业生自我鉴定
2014/01/12 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
2014年小学数学教师工作总结
2014/12/03 职场文书
2014年前台接待工作总结
2014/12/05 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书
Java tomcat手动配置servlet详解
2021/11/27 Java/Android
微信小程序中wxs文件的一些妙用分享
2022/02/18 Javascript