• 深入理解javascript之IIFE


    IIFE的全称是Immediately-invoked Function Expression,立即执行函数表达式

    在讲IIEF之前,我们首先需要区分函数表达式和函数声明。

    var test = function(){};

    这个叫做函数表达式

    function test(){};

    这个叫做函数声明

    函数表达式中的函数可以为匿名函数,也可以有函数名,但是该函数实际上不能直接使用,只能通过表达式左边的变量test来调用。

    如果我们要调用函数表达式,通过以下方式即可:

    var test = function(){};
    test();

    如果我们直接使用匿名函数:

    function(){}()//SyntaxError:Unexpected token(

    就会报错,这是因为浏览器引擎在解释javascript时,遇到function关键字时,会默认把它当做一个函数声明,而不是函数表达式。而函数声明如我们上面所说,需要一个函数名,所以浏览器会认为上面的代码为匿名函数声明,所以报错。

    但是,这里需要注意,即使我们给它一个函数名,它依然会报错:

    function test(){}();//SyntaxError:Unexpected token )

    为什么会这样呢?在一个函数表达式后面加上括号,表示该表达式立即执行。但是如果是在一条语句后面加上括号,那么该括号只是用来控制优先级的。所以上面的代码相当于声明了一个函数然后执行()语句,但是()中内容为空,所以报错

    所以最后的解决办法就是写成如下形式:

    (function (){}());

    这样就不会报错了,因为当解释器遇到(后,会认为其中的function不是函数声明而是函数表达式,所以就成功啦。

    IIFE可以带来块状作用域效果:

    var a = 2;
      (function IIFE(){
         var a = 3;
         console.log( a );   // 3
     })();
     console.log( a );       // 2

    当然,还有其他多种方法立即执行匿名函数:

    (function(){})(); 
    void function(){}(); //使用void 
    !function(){}();//使用一元运算符
    ~function(){}();
    -function(){}();
    +function(){}();

    在Bootstrap源码中就使用了大量的IIFE:

    +function ($) { }(window.jQuery);

    最后,注意一下函数表达式和函数声明的使用。请看代码:

    if (true) {
        var foo = function(){
            document.write( "1" );
        }
    }
    else {
       var foo = function(){
            document.write( "2" );
        }
    }
    foo();//1

    输出结果为1,这个很好理解,那么我们调整一下执行foo的位置呢:

    foo();//undefined
    if (true) {
        var foo = function(){
            document.write( "1" );
        }
    }
    else {
       var foo = function(){
            document.write( "2" );
        }
    }

    这里就是未定义。这是由于变量提升。javascript解释器在解释代码时会将变量声明先提升到块级作用域最前端,也就是这个样子:

    var foo;
    foo();//undefined
    if (true) {
        foo = function(){
            document.write( "1" );
        }
    }
    else {
       foo = function(){
            document.write( "2" );
        }
    }

    那么我们看看使用函数声明时的结果:

    if (true) {
        function foo() {
            document.write( "1" );
        }
    }
    else {
        function foo() {
            document.write( "2" );
        }
    }
    
    foo();      // 2

    咦,这里怎么又输出2了呢?原来函数声明和变量一样,都有一个提升的过程,而和函数表达式只会提升声明不一样,函数声明即会提升声明,也会提升定义,所以第二个foo的定义把第一个foo给替换掉了。

    转自:http://blog.csdn.net/mevicky/article/details/49474143

  • 相关阅读:
    缓存架构设计细节二三事
    啥,又要为表增加一列属性?
    SpringMvc4.x---快捷的ViewController
    SpringMvc4.x--@ControllerAdvice注解
    SpringMvc4.x--Spring MVC的常用注解
    解决svn--Unable to connect to a repository at URL ‘https://xxxxxx’ 问题
    或许你不知道的10条SQL技巧
    Java 基础-运算符
    Java 运算符 % 和 /
    Java基础-注释
  • 原文地址:https://www.cnblogs.com/zhumingyong/p/8473262.html
Copyright © 2020-2023  润新知