IIFE-立即执行函数表达式

IIFE,全拼是 Immediately-Invoked Function Expression 。

函数声明与函数表达式

函数声明
function foo () {
  console.log('Hi foo')
}
函数表达式
var fuu = function () {
  console.log('Hi fuu')
}
区别

函数声明与变量声明一样,会在代码本身被执行前(编译阶段)先提升到各自作用域的顶端。(注意:函数声明提升优先于变量声明的提升)

foo() // Hi foo
fuu() // Uncaught TypeError: fuu is not a function

// 函数声明会提升
function foo () {
  console.log('Hi foo')
}
// 函数表达式不会提升
var fuu = function () {
  console.log('Hi fuu')
}

 IIFE知识点

// 报错原因:函数声明关键字function后未提供函数名
function(){ /* code */}() // Uncaught SyntaxError: Function statements require a function name

// 报错原因:第二个圆括号被认为是运算符,需要包裹表达式
function foo(){ /* code */ }() // Uncaught SyntaxError: Unexpected token )

// 正确执行,输出1
function foo(){/* code */}(1) 

// 上面的代码等同于如下,一个函数声明跟着一个完全没有关系的表达式
function foo(){/* code */}
(1)

// 在函数表达式中允许匿名函数,这比较符合认知
var foo = function(){console.log('Yes')}() // 输出Yes。但foo是undefined,因为并没有值可赋给它。

// 当圆括号包裹函数时,它会默认将函数作为表达式去解析,而不是函数声明
( function(){console.log('Yes')} )() 
( function foo(){ console.log('Yes')} )()

// 外层括号内的表达式是立即执行函数表达式^_^
( function(){console.log('Yes')} () )
( function foo(){console.log('Yes')} () )

// 以上立即执行函数表达式都可以将return值赋值给一个变量
var res = ( function foo(){return 'Yes'} () )

关于圆括号 ( ) 运算符,《JavaScript高级程序设计》一书中没有介绍,MDN上介绍为:圆括号运算符 ( ) 用于控制表达式中的运算优先级,比如 (1 + 2) * 3 。哦,恍然大悟。 所以 ( ) 运算符中必须要有表达式,否则报语法错误。

问题代码解析

console.log(1, typeof g)
var f=function(){return true};
console.log(2, typeof g)
var g=function(){return false};
console.log(3, typeof g);
;(function(){
    console.log(4, typeof g)
    if ((g() && []) == ![]) {
    console.log(5, typeof g)
        f = function(){return false};
        console.log(6, typeof g)
        function g() {return true};
        console.log(7, typeof g)
    }
    console.log(8, typeof g)
}
)();
console.log(9, typeof g)

var c = f();
console.log(10, typeof g)
var b = g();
console.log(11, typeof g)

执行以上代码会报 g is not a function,原因是在第4个console后面执行g()的时候,因为下面的函数声明function g(),此时有g变量,但是值为undefined,所以报错 

posted on 2019-03-10 22:06  dawnxuuu  阅读(150)  评论(0编辑  收藏  举报

导航