先看一段代码:
function diTui(n) {
if(n===1){
return n
}
return diTui(n-1)*n
}
var test=diTui;
test=undefined;
test(5);
问,这段代码可以有效执行吗?
答:不可以,在diTui被赋值为undefined的时候,它就已经失效了
其实是不对的,他考察的点还没在这
再看一段代码:
function diGui(n) {
if(n===1){
return n
}
return arguments.callee(n-1)*n
}
var test=diGui;
test(5);
这个代码可以正常运行
很明显的发现,我们在递归的时候使用了args的一个属性,args.callee来代替指向正在执行的这个匿名函数。
arguments
1.arguments不是数组,但是有数组的length和索引元素属性
2.arguments转化为一个数组var args=Array.prototype.slice.apply(str,arguments)
3.arguments定义了callee和caller属性。
4.所有(箭头函数除外)函数的局部变量,可以使用args对象在函数中引用函数的参数。
5.arguments是一个对象。
arguments.callee(指向当前执行的函数)
- 匿名递归函数中使用,可以实现函数名与函数之间的解耦,在修改完函数名之后,函数内部可以保持不变。
function jieChen(){
return function(n){
if(n<=1) return 1
return n*arguments.callee(n-1)
}
}
- 替换方案,因为args.callee使用的代价很大啊
function jieChen(n){
if(n<=1) return 1;
let result=1;
return (function fn(){
result*=n
n--;
if(n!=0){
fn()
}
return result
})()
}
有一个面试题:
接受参数弄,循环输出数组【1,2,3,4,5】,不能使用for循环。
function show(n){
let result=[]
return (function () {
result.unshift(n)
n--
if(n!=0){
arguments.callee();
}
return result
})()
}
arguments.caller(指向调用当前函数的函数)
function whoCalled() {
if (arguments.caller == null)
console.log('该函数在全局作用域内被调用.');
else
console.log(arguments.caller + '调用了我!');
}