arguments.callee 应用场景
表示的是函数本身,用于递归调用
let obj = {
name:'john',
fn:function(n){
console.log(this)
n++;
if(n>15) return;
console.log(n)
obj.fn(n); // 调用自己 这样也可以 跟下面的区别是this的指向不同 this -> obj
arguments.callee(n) // this 是 arguments
}
}
obj.fn()
(function(i){
if(i>=3) return;
arguments.callee(++i) // 这种情况下只能用arguments.callee()
})(1)
但是JS严格模式下,不支持arguments.callee(),此时我们该如何实现匿名函数下的递归呢?
即 匿名函数“具名化”
匿名函数“具名化”定义
给函数表达式的函数起的名字。 匿名函数“具名化”是非常规范的操作。
作用和特点
防止全局污染
-
此名字不能在外面访问,也就是不会在当前上下文中创建这个名字。当函数执行,在形成的私有上下文中,会把这个具名化的名字作为私有上下文中的变量(值就是这个函数)来进行处理。
-
在本函数的上下文中使用,它的值是不会被修改的。(有特殊性)
-
除非当前的名字被上下文中的其他变量声明过,则名字是私有变量,和具名化的函数没有任何的关系了。这个时候才可以更改。
var func = function AAA(){ // 当函数执行,在形成的私有上下文中,会把这个具名化的名字作为私有上下文中的变量(值就是这个函数)来进行处理。 console.log(AAA) // AAA() 递归调用,而不用严格模式下都不支持的 arguments.callee了。当然此处也可以用func 但是如果是自执行函数,没有func这个变量呢? } AAA() // error:AAA is not defined func() // JS严格模式下,不支持arguments.callee() "use strict" (function b(i){ if(i>=3) return; b(++i) // 这种情况下只能用arguments.callee() 而有了具名化 就可以用具名化的变量了 })(1) //匿名函数“具名化”的特点 这个函数名对应的值不可以被修改 (function b(){ console.log(b); // function b(){} b = 100; console.log(b); // function b(){} })() //匿名函数“具名化”的特点 这个函数名对应的值修改的条件是重新声明 (function b(){ console.log(b); // undefined var b = 100; console.log(b); // 100 })() (function b(){ // 注释掉 即可 用let console.log(b); // 报错 不可以初始化之前访问b let b = 100; console.log(b); // 100 })()
应用场景
setTimeout(function func(){ // 匿名函数“具名化”
func()
},1000)