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 相关文章推荐
仅IE支持clearAttributes/mergeAttributes方法使用介绍
May 04 Javascript
如何用ajax来创建一个XMLHttpRequest对象
Dec 10 Javascript
jquery分页插件AmSetPager(自写)
Apr 15 Javascript
Javascript之this关键字深入解析
Nov 12 Javascript
node.js中的fs.ftruncate方法使用说明
Dec 15 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
Jun 26 Javascript
vue2.0多条件搜索组件使用详解
Mar 26 Javascript
深入浅析javascript继承体系
Oct 23 Javascript
JS获取当前地理位置的方法
Oct 25 Javascript
小程序如何写动态标签的实现方法
Feb 05 Javascript
JavaScript对象字面量和构造函数原理与用法详解
Apr 18 Javascript
vue实现单一筛选、删除筛选条件
Oct 26 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
将文件夹压缩成zip文件的php代码
2009/12/14 PHP
php数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
2011/10/31 PHP
php分页思路以及在ZF中的使用
2012/05/30 PHP
PHP fopen()和 file_get_contents()应用与差异介绍
2014/03/19 PHP
微信公众平台消息接口校验与消息接口响应实例
2014/12/23 PHP
php将数组存储为文本文件方法汇总
2015/10/28 PHP
通过PHP简单实例介绍文件上传
2015/12/16 PHP
Yii框架学习笔记之应用组件操作示例
2019/11/13 PHP
基于jquery的tab切换 js原理
2010/04/01 Javascript
JavaScript中对象property的删除方法介绍
2014/12/30 Javascript
jquery转盘抽奖功能实现
2015/11/13 Javascript
基于jQuery实现响应式圆形图片轮播特效
2015/11/25 Javascript
javascript数据类型验证方法
2015/12/31 Javascript
js正则表达式replace替换变量方法
2016/05/21 Javascript
在一个页面重复使用一个js函数的方法详解
2016/12/26 Javascript
浅谈js-FCC算法Friendly Date Ranges(详解)
2017/04/10 Javascript
vue的全局提示框组件实例代码
2018/02/26 Javascript
微信小程序实现换肤功能
2018/03/14 Javascript
vuex与组件联合使用的方法
2018/05/10 Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
2019/01/18 Javascript
用element的upload组件实现多图片上传和压缩的示例代码
2019/02/12 Javascript
微信小程序开发打开另一个小程序的实现方法
2020/05/17 Javascript
[01:02:55]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
详解Python3.6安装psutil模块和功能简介
2018/05/30 Python
Python continue继续循环用法总结
2018/06/10 Python
mac下如何将python2.7改为python3
2018/07/13 Python
Python解析命令行读取参数之argparse模块
2019/07/26 Python
python 字段拆分详解
2019/12/17 Python
python保留小数位的三种实现方法
2020/01/07 Python
TensorFlow绘制loss/accuracy曲线的实例
2020/01/21 Python
含精油的天然有机化妆品:Indemne
2019/08/27 全球购物
党员个人思想汇报
2013/12/28 职场文书
应届行政管理专业个人自我评价
2013/12/28 职场文书
毕业论文评语大全
2014/04/29 职场文书
2015年城市管理工作总结
2015/05/23 职场文书
导游词之永泰公主墓
2019/12/04 职场文书