caller、callee是与javascript函数相关的两个属性,今天来总结下。

Function.caller

caller是javascript函数的一个属性,它指向调用当前函数的函数,如果函数是在全局范围内调用的话,那么caller的值为null。

function outer() {
inner();
}
function inner() {
if(inner.caller==null) { //值为null,在全局作用域下调用
console.log("我是在全局环境下调用的");
} else {
console.log(inner.caller+"调用了我");
}
}
inner();
outer();

arguments.callee

arguments是函数内部中一个特殊的对象,callee是arguments的属性之一, 他指向拥有该arguments的函数对象。在某些不方便暴露函数名的情况下, 可以用arguments.callee代替函数名。但是,在严格模式(“use strict;”)下访问arguments.callee会抛出 TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them 错误

现在我们来仔细看看上面那段代码。如果老板说:“不行,函数名叫inner不好听,给我改!” 改代码容易,但是想改了后不出错误那可就难了。 这时我们就可以使用argument.callee来代替函数名,减少修改代码的地方,从而降低出错率

function outer() {
inner();
}
function inner() { //只需改这个函数名,而不需要改内部代码
if(arguments.callee.caller==null) {
console.log("我是在全局环境下调用的");
} else {
console.log(arguments.callee.caller+"调用了我");
}
}
inner();
outer();

除此之外,当我们写递归函数时,也会在函数里面暴露函数名,此时也会产生问题,如下。

/**
* factorial:阶乘
*/
function factorial(n) {
if(n<=1) {
return 1;
} else {
return n*factorial(n-1);
}
}
console.log(factorial(3)); //
var foo = factorial;
console.log(foo(3)); //
factorial = null;
console.log(foo(3)); //Error:factorial is not a function

factorial置为null,虽然foo指向了factorial使其不会被销毁, 但是原函数内部的函数名任然是factorial,自然应找不到而报错。 此时我们就可以用arguments.callee代替函数名

function factorial(n) {
if(n<=1) {
return 1;
} else {
return n*arguments.callee(n-1);
}
}

那还能不能更强点?毕竟arguments.callee在严格模式下是无法访问的,肯定没法儿用啊!

var factorial = (function foo(n) {
if(n<=1) {
return 1;
} else {
return n*foo(n-1); //内部可访问foo
}
});
foo(6); //ReferenceError: foo is not defined

以上代码利用命名函数表达式的形式创建了一个递归函数。 这有两个好处:第一,严格模式下函数任然能照常运转; 第二,性能优于argument.callee。注意foo仅在其函数体内可访问,在外是访问不到的。

arguments.caller

arguments.caller 这是我们遇到的第二个caller,没啥用,在严格模式下无法访问,非严格模式下值也为undefined,而且貌似被废弃了

总结

1.Function.caller指向调用该函数的函数

2.arguments.callee指向拥有该arguments的函数

3.arguments.caller没啥用

引用

1.《javascript高级程序设计》

2.MDN

  2.1 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/caller

  2.2 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller

  2.3 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/callee

Function.caller、arguments.caller、argument.callee的更多相关文章

  1. 第4天:function对象(案例:获取当前日期属于当年第几天、arguments对象、函数类型、参数、返回值、自身调用)

    获取当前日期输入当年第几天 //输入,年月日,获取这个日期是这一年的第几天 //年-月--日:20171月31日 function getDay(year,month,day){ //定义变量存储对应 ...

  2. JavaScript学习总结(三、函数声明和表达式、this、闭包和引用、arguments对象、函数间传递参数)

    一.函数声明和表达式 函数声明: function test() {}; test();    //运行正常 function test() {}; 函数表达式: var test = functio ...

  3. (O)JS:执行环境、变量对象、活动对象和作用域链(原创)

    var a=1; function b(x){ var c=2; console.log(x); } b(3); ·执行环境(execution context),也称为环境.执行上下文.上下文环境. ...

  4. 引用类型--Function类型(函数声明与函数表达式、arguments.callee、caller、apply、call、bind)

    在ECMAScript中函数实际上是对象.每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定 ...

  5. js中函数的 this、arguments 、caller,call(),apply(),bind()

    在函数内部有两个特殊的对象,arguments 和 this,还有一个函数对象的属性caller. arguments对象 arguments是一个类似数组的对象,包含着传入函数的所有参数. func ...

  6. Function.caller, arguments.caller, arguments.callee, arguments.callee.calller

    Function.caller指向当前函数的调用者,是arguments.caller的替代者 arguments.caller也是指向当前函数的调用者,已被废弃 arguments.callee是对 ...

  7. javascript下的arguments,caller,callee,call,apply示例及理解

    (参考:http://justcoding.iteye.com/blog/589111) Arguments  该对象代表正在执行的函数和调用它的函数的参数. [function.]arguments ...

  8. javascript 之Function对象的apply(),call(),bind(),方法和arguments,caller,length属性

    注:这篇文章原文:http://www.jb51.net/article/30883.htm 自己作为学习,重新写写. 一.写在前面的话 前端javascript编程还只是略懂皮毛,DOM知道一点,j ...

  9. Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)

    代码重构,为了确保功能的等效性,梳理代码时,发现如下代码: public SingleRespTTO fundI(SingleReqTTO request) throws Exception { re ...

随机推荐

  1. 手机web——自适应网页设计(html/css控制) - 51CTO.COM

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  2. sqlserver数据库类型对应Java中的数据类型

    SQL Server 类型 JDBC 类型 (java.sql.Types) Java 语言类型 bigint BIGINT long timestamp binary BINARY byte[] b ...

  3. [iOS]使用signal让app能够在从容崩溃

    前言 虽然大家都不愿意看到程序崩溃,但可能崩溃是每个应用必须面对的现实,既然崩溃已经发生,无法阻挡了,那我们就让它崩也崩得淡定点吧. iOS SDK中提供了一个现成的函数 NSSetUncaughtE ...

  4. 关于JAVA中hashCode

    hash code 即散列码根据对象计算出的一个整型值,散列码是没有规律的. 如果两个对象相等(equal() 返回true),则hashCode一定相等,如果两个对象hashCode相等,则对象不一 ...

  5. 源码解析-knockout源码准备

    准备包括心理和资源两方面. 心理 我看过一句话说,当你用一个框架时,不要忙着看一遍使用教程就开始写项目,先去看看框架原理. 这句话我深以为然.现今前端快速发展,很多前端攻城狮都很茫然:框架更新太快了, ...

  6. 批量删除ASP.NET中的缓存(cache)

    IDictionaryEnumerator em = HttpContext.Current.Cache.GetEnumerator(); while (em.MoveNext())        { ...

  7. IOS9中联系人对象的使用及增删改查操作的函数封装

    之前克服重重困难把IOS9中新的类联系人搞明白了,现在把增删改查封装成了函数,如下: // // ViewController.m // IOS9中联系人CNContact的使用 // // Crea ...

  8. 《Web接口开发与自动化测试 -- 基于Python语言》 ---前言

    前    言 本书的原型是我整理一份Django学习文档,从事软件测试工作的这六.七年来,一直有整理学习资料的习惯,这种学习理解再输出的方式对我非常受用,博客和文档是我主要的输出形式,这些输出同时也帮 ...

  9. android 菜单的总结

    安卓菜单有三种菜单. 选项菜单: 点击系统菜单按钮会触发 上下文菜单:长按屏幕触发 子菜单:某一个菜单的下一级菜单 具体的描叙:http://blog.csdn.net/zqiang_55/artic ...

  10. easyui 使用随笔

    1,datagrid 翻页,记住翻页前的复选框. 在onLoadSuccess:function 中,去掉 清楚选择选项 onLoadSuccess:function(){ //tab.datagri ...