美文网首页
JavaScript浅析 -- IIFE立即执行函数表达式

JavaScript浅析 -- IIFE立即执行函数表达式

作者: Da_xiong | 来源:发表于2018-06-03 16:56 被阅读0次

    一、什么是IIFE?

    所谓IIFE(Immediately-Invoked Function Expression)翻译过来就是立即执行函数表达式。其实就是

    1. 声明了一个函数。
    2. 立即执行这个函数。

    他有好多种写法,如下代码就是经典的写法:

    (function() { console.log('立即执行') })()
    

    如上,前面是一个函数,然后调用函数是‘函数名()’,所以后面加()执行该函数。这个比较好理解,那前面那个为啥要加括号呢?不加可以不?我们来试试:

    function() { console.log('立即执行') }() // Uncaught SyntaxError: Unexpected token (
    

    结果是报错Uncaught SyntaxError: Unexpected token (,为啥呢?其实因为js解释代码的时候遇到function会认为是一个函数声明,而声明函数却没有找到函数名,所以遇到第一个左括号就报错了。接着我们加上函数名修改如下:

    function func() { console.log('立即执行') }() // Uncaught SyntaxError: Unexpected token )
    

    还是报错Uncaught SyntaxError: Unexpected token ),好在错误变了,不过这次又是为啥?其实因为前面的函数声明包含函数名已经是一个完整的语句了,所以后面的()又另做为一个语句。相当于如下代码:

    function func() { console.log('立即执行') };
    ();
    

    而分组操作符()中的表达式又不能为空,所以是遇到最后一个右括号才报的错。那怎样才能让两者并成一个语句从而实现函数的执行呢?

    为了解决上面的两个问题,只要让其变成表达式,加个括号就行了,因为括号内部不能有语句所以会认为是一个表达式。有如下两种写法:

    • (function func(){})()
    • (function func(){}())

    其原理都是一样的,都是为了让其变成一个表达式。而其实让他变成表达式的写法不止上面两种,上面两种是比较经典易读的写法。还有如下几种,原理都是一样的:

    // 运算符直接转表达式法
    var i = function(){ console.log('立即执行') }();
    !function(){ console.log('立即执行') }();
    ~function(){ console.log('立即执行') }();
    -function(){ console.log('立即执行') }();
    +function(){ console.log('立即执行') }();
    
    // 解析器在遇到& || ,等操作符时,会把两边默认为表达式。
    // 但注意交换位置就不行,因为如果把function放在前面则还是会认为是声明
    true & function(){ console.log('立即执行') }();
    0, function(){ console.log('立即执行') }();
    
    // 以及new
    new function(){ console.log('立即执行') }
    new function(){ console.log('立即执行') }() // 带参数
    

    二、IIFE有啥用?

    先来看个例子,如下声明了一个变量i并输出:

    var i = 0;
    console.log(i);
    

    但是这样做有时候会有一个问题,在这个全局作用域下声明的i会影响到整个作用域(全局污染),也就是整个全局作用域下的i都变成了0,而我们只是单纯想在这里可用,应该怎么做呢?在Js(ES6之前)里只分为全局作用域和局部作用域 ,局部作用域一般是通过函数来创建一个单独的作用域,这个作用域下只有函数内可用。所以将上面改写如下:

    function a() {
        var i = 0;
        console.log(i);
    }
    a();
    

    这样的话,i就只在函数a里面才有效。可是。。。却多出来一个变量a,还是污染了全局。其实这个a也是可以避免的,因为我们声明了这个函数只是想利用他的局部作用域而已,声明完就立马执行了,何必起个名字呢。所以再进一步改写如下:

    (function() {
        var i = 0;
        console.log(i);
    })()
    

    这样立即执行函数表达式就诞生了,神奇吧?(其实还是挺鸡肋的,代码写的这么复杂只是想创建一个不污染全局的变量而已,在ES6之后有了块级作用域和let等,这些问题得到了改善)。
    所以经过上面的例子,我们大概就能体会立即执行函数表达式有啥用了。简单来说:

    • IIFE的作用就是创建一个独立的作用域。在这个作用域里面的变量只有其内可以访问,从而避免变量污染

    相关文章

      网友评论

          本文标题:JavaScript浅析 -- IIFE立即执行函数表达式

          本文链接:https://www.haomeiwen.com/subject/zcnxkftx.html