Appearance
匿名函数
IIFE
(function () {})()
~function () {}()
-function () {}()
!function () {}()
+function () {}()
函数表达式
const foo = function () {}
回调函数
setTimeout(() => {})
匿名函数具名化
函数名并不会在所处上下文中进行声明,只能在函数体内部访问,函数外部访问不到。
~(function foo () {})() const bar = function baz () {}
console.log(foo) // foo is not defined console.log(baz) // baz is not defined
函数名不能再绑定为其它值。
~(function foo () { foo = 100 // 无效 console.log(foo) // 函数本身 })()
创建 NFE 时,创建了一个专门的 Lexical Environment(词法环境)用于保存 foo,并且创建 的是不可更改的绑定。
函数体内直接访问 foo,由于形参中没有 foo,函数体内也没有声明过 foo,按理来说要去上级 作用域查找,但是由于 NFE 创建了一个专门的词法环境,先去这里找,成功找到了 foo,并且 由于设置了不可更改,对 foo 的修改也无效。
foo 并没有保存在上级作用域的词法环境中,故不能从函数体外部访问。
如果在函数内部,foo 出现在形参中或被声明过(var、fucntion、let、const、class、import) 则 AO(FN) 中会保存 foo,内部访问时会优先找 AO(FN),之前的修改无效,也就不成立了。
作用
- 递归
javascript
~(function foo () {
foo()
})()
~(function () {
arguments.callee // 代表当前函数本身
arguments.callee() // 实现递归,但是在严格模式下不允许使用 arguments.callee
})()EC(FN)
fn -×-> 堆内存
fn ---> undefined
作用域链
形参赋值
变量提升: var fn
js
~(function fn () {
console.log(fn) // undefined
var fn = 100 // 有效操作
console.log(fn) // 100
})()
~(function fn (fn) {
console.log(fn) // 100
var fn = 200
console.log(fn) // 200
})(100)
~(function fn () {
let fn = 100
console.log(fn) // 100
})()
~(function fn (fn) {
console.log(fn) // function fn () {}
function fn () {} // 变量提升
console.log(fn) // function fn () {}
})(100)js
// example
var b = 10
~(function b () {
b = 20
console.log(b)
})()
console.log(b)