JavaScript arguments
arguments
arguments.callee
function.caller
一、callee
callee是干什么的呢?
首先arguments是一个对象或叫类数组、数组、实参列表,它上面还有些属性包括length、callee。
这个callee指向的就是这个函数的引用,引用什么意思意思,就是函数自己。
function test(){ console.log(arguments.callee); } test(); // ƒ test(){console.log(arguments.callee);}
arguments.callee 指代的就是这个test,arguments.callee == test 是相等的
function test(){ console.log(arguments.callee == test); // arguments.callee == test } test(); // true
这有什么用吗?还真有点用,下面看一小例子,
前面学过立即执行函数,立即执行函数是一个初始化的工具,当要初始化一个非常的复杂数据,经过一些列复杂计算的话,用立即执行函数是最好的,因为用完一遍函数后,不用第二遍了省空间。
现在要初始化一个数据是100的阶乘,初始化数据执行一遍就完事了,最好是立即执行函数。
var num = (function(n){ if(n == 1){ return 1; } return n * 阶乘(n-1); }(100))
阶乘最好用递归来写,
1). 先找出口 if(n == 1){ return 1; } 然后 return n * 阶乘(n -1)
2). 请把这个函数该补全的地方补全,这个函数差哪?
差的就是写"阶乘"汉字的这块,能替代的吗?
3). 原来用递归很简单是这样写的return n * fn(n-1) ,
现在这个函数连名字都没有,连名都没有怎么调用自身用递归?
要找到函数自己的引用,找到引用最好就是arguments.callee
var num = (function(n){ if(n == 1){ return 1; } return n * arguments.callee(n-1); }(100)) console.log(num); // 2432902008176640000
这种情况下只能用arguments.callee来解决这个问题,因为立即执行函数没有名,有名也没用,只能用arguments.callee,arguments.callee指向函数自身引用。
看一个问题
function test(){ console.log(arguments.callee); function demo(){ console.log(arguments.callee); } demo(); } test(); // 第一个打印test,第二个打印demo
在那个函数里面的arguments,就指代的那个函数。
二、caller
再来一个知识点caller,这个caller本质上真没太大用,但callee和caller经常在一起考。
caller不是arguments上的属性,arguments上的属性只有callee和length,
这个caller是函数自己的属性就像prototype。
caller是什么意思?
叫他的那个人,demo.caller就是demo在那个环境里,被调用的那个环境。
function test(){ demo(); } function demo(){ console.log(demo.caller); } test(); // ƒ test(){demo();}
现在demo被调用的环境是test,所以demo.caller打印返回 ƒ test(){demo();}
caller、callee没什么用,而且在es5标准模式里面也不让用了
"use strict"; function test(){ demo(); } function demo(){ console.log(demo.caller); } test(); // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them