Function.caller、arguments.caller、argument.callee
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的更多相关文章
- 第4天:function对象(案例:获取当前日期属于当年第几天、arguments对象、函数类型、参数、返回值、自身调用)
获取当前日期输入当年第几天 //输入,年月日,获取这个日期是这一年的第几天 //年-月--日:20171月31日 function getDay(year,month,day){ //定义变量存储对应 ...
- JavaScript学习总结(三、函数声明和表达式、this、闭包和引用、arguments对象、函数间传递参数)
一.函数声明和表达式 函数声明: function test() {}; test(); //运行正常 function test() {}; 函数表达式: var test = functio ...
- (O)JS:执行环境、变量对象、活动对象和作用域链(原创)
var a=1; function b(x){ var c=2; console.log(x); } b(3); ·执行环境(execution context),也称为环境.执行上下文.上下文环境. ...
- 引用类型--Function类型(函数声明与函数表达式、arguments.callee、caller、apply、call、bind)
在ECMAScript中函数实际上是对象.每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定 ...
- js中函数的 this、arguments 、caller,call(),apply(),bind()
在函数内部有两个特殊的对象,arguments 和 this,还有一个函数对象的属性caller. arguments对象 arguments是一个类似数组的对象,包含着传入函数的所有参数. func ...
- Function.caller, arguments.caller, arguments.callee, arguments.callee.calller
Function.caller指向当前函数的调用者,是arguments.caller的替代者 arguments.caller也是指向当前函数的调用者,已被废弃 arguments.callee是对 ...
- javascript下的arguments,caller,callee,call,apply示例及理解
(参考:http://justcoding.iteye.com/blog/589111) Arguments 该对象代表正在执行的函数和调用它的函数的参数. [function.]arguments ...
- javascript 之Function对象的apply(),call(),bind(),方法和arguments,caller,length属性
注:这篇文章原文:http://www.jb51.net/article/30883.htm 自己作为学习,重新写写. 一.写在前面的话 前端javascript编程还只是略懂皮毛,DOM知道一点,j ...
- Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)
代码重构,为了确保功能的等效性,梳理代码时,发现如下代码: public SingleRespTTO fundI(SingleReqTTO request) throws Exception { re ...
随机推荐
- mysqldump导入导出mysql数据库
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- MySQL索引背后的之使用策略及优化(高性能索引策略)
为了讨论索引策略,需要一个数据量不算小的数据库作为示例.本文选用MySQL官方文档中提供的示例数据库之一:employees.这个数据库关系复杂度适中,且数据量较大.下图是这个数据库的E-R关系图(引 ...
- redis 学习
http://blog.csdn.net/z69183787/article/category/2923783
- 23、手把手教你Extjs5(二十三)模块Form的自定义的设计[2]
在本节中将要加入各种类型的字段,在加入字段的时候由于可以一行加入多个字段,因此层次结构又多了一层fieldcontainer.form里面的主要层次结构如下: form -- fieldSet -- ...
- 18、手把手教你Extjs5(十八)模块记录的拖放删除、拖放复制新增
网页当中的拖放(drag-drop)是比较有趣的操作,extjs5中很好的封装了拖放的动作,也有各种类来支持,但是要学好“拖放”这个东西真是很难,特别是象我这样英语不好的人,看不太懂官网上的说明,做一 ...
- HCSR04超声波传感器驱动
HC_SR04是一款使用较为广泛的超声波测距模块,模块图如下 该模块具有四个引脚,分别为VCC GND TRIG ECHO,其中VCC GND为供电脚 TRIG为测距触发引脚,ECHO为测距输入引脚 ...
- 关于中值滤波算法,以及C语言实现(转)
源:关于中值滤波算法,以及C语言实现 1.什么是中值滤波? 中值滤波是对一个滑动窗口内的诸像素灰度值排序,用其中值代替窗口中心象素的原来灰度值,它是一种非线性的图像平滑法,它对脉冲干扰级椒盐噪声的抑制 ...
- NavigationView学习笔记
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/an ...
- Nodejs之发送邮件nodemailer
nodejs邮件模块nodemailer的使用说明 1.介绍 nodemailer是node的一个发送邮件的组件,其功能相当强大,普通邮件,传送附件,邮件加密等等都能实现,而且操作也十分方便. nod ...
- Grid (read-only) objects and methods (client-side reference)获取子表单对象的一些方法 Crm 2016
https://msdn.microsoft.com/en-us/library/dn932126.aspx#BKMK_GridControl Updated: November 29, 2016 A ...