• js中函数表达式和自执行函数表达式的用法总结


    立即调用函数表达式

    • 给函数体加大括号,在有变量声明的情形下,没有任何区别
    • 但是,如果只是【自动执行】的情形下,就会不同
    • 因为,一个匿名函数,不赋值或函数体不加小括号,是不能自动执行的
    //以下情形并无差别
    var count100 = function getCount100(){ return(100) }();//100
    var count200 = (function getCount200(){ return(200) })();//200,加小括号和count100没有区别
    var count = (function getCount(n){ return(n) })(300);//300,传参的情形
    //不赋值变量,函数体加小括号,自动执行
    (function aaa(){console.log("aaa")})();// aaa
    console.log(aaa);//aaa is not defined
    //一个匿名函数,函数体不加小括号,是不能自动执行的
    function bbb(){console.log("bbb")}();//Unexpected token )
    
    • 实际上【自执行函数表达式】可以有很多复杂的情形,比如下边的复杂例子
    //函数声明置于小括号中,没有自执行
    ( function fn(){console.log("aaa");return "bbb"} );
    console.log("fn res is " + fn);// fn is not defined
    
    //函数声明置于小括号中,且自执行
    ( function fn(){console.log("aaa");return "bbb"}() );//输出aaa
    console.log("fn res is " + fn);// fn is not defined
    
    //函数声明置于小括号中,且自执行,注意,负责执行的一对小括号移到了外部
    ( function fn(){console.log("aaa");return "bbb"} )();//输出aaa
    console.log("fn res is " + fn);// fn is not defined
    
    //函数声明置于小括号中,函数未执行但将其赋值给fn
    ( fn = function aaa(){console.log("aaa");return "bbb"} )
    console.log("fn res is " + fn());//fn res is bbb
    
    //函数声明置于小括号中,函数执行,并且将其赋值给fn
    ( fn = function aaa(){console.log("aaa");return "bbb"}() );//输出aaa
    console.log("fn res is " + fn);//fn res is bbb
    
    //函数声明置于小括号中,将其赋值给fn,并且在外部执行之(注意末尾小括号位置)
    ( fn = function aaa(){console.log("aaa");return "bbb"} )();//输出aaa
    console.log("fn res is " + fn());//再次输出aaa,并输出fn res is bbb
    
    // 匿名函数在自执行,注意末尾小括号位置
    ( function(){console.log("aaa");return "bbb"} )();//输出aaa
    
    // 匿名函数在自执行,可见和上边的例子效果一致
    ( function(){console.log("aaa");return "bbb"}() );//输出aaa
    
    //在括号外赋值的函数表达式,例一。以下三例的结果是一致的
    var fn = function aaa(){return "bbb"}();
    console.log("fn is res " + fn);//fn is res bbb
    //例二
    var fn = (function aaa(){return "bbb"})();
    console.log("fn is res " + fn);//fn is res bbb
    //例三
    var fn = (function(){return "bbb"})();
    console.log("fn is res " + fn);//fn is res bbb
    -------
    
    //正常的函数,注意fn的name属性自动设置为fn
    function fn(){return "bbb"};
    console.log(fn.name);//fn
    console.log("fn is res " + fn());//fn is res bbb
    //函数表达式,注意fn的name属性是fn
    var fn = function(){return "bbb"};
    console.log(fn.name);//fn
    console.log("fn is res " + fn());//fn is res bbb
    //函数表达式,注意fn的name属性是aaa
    var fn = function aaa(){return "bbb"};
    console.log(fn.name);//aaa
    console.log("fn is res " + fn());//fn is res bbb
    
    

    对于如此多的不同情形,可以总结如下:

    • 在不赋值的情形下,在小括号中的函数或者函数表达式,被阻止声明为一个全局的变量,同时其内部是可执行的
    • 但如果其在小括号中,被赋值给了某一变量,那么该函数或者函数表达式就会被曝露出去,可以在外部调用
    • 函数表达式在赋值给一个变量时,该变量会拥有一个name属性,它的值取决于函数表达式是否为匿名函数
    • 如果为匿名函数,则变量的name属性值为自身,如果为具名函数,则变量的name属性值为具名函数的name值
    • 影响表达式执行的末尾的一对小括号,对词法上的影响很小
    • 即,影响函数表达式的因素,由大到小是: 赋值与否 => 匿名与否 => 何时执行
  • 相关阅读:
    【BZOJ 3090】 树形DP
    【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)
    【BZOJ 1019】 1019: [SHOI2008]汉诺塔 (DP?)
    【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)
    【BZOJ 3566】 3566: [SHOI2014]概率充电器 (概率树形DP)
    【BZOJ 2121】 (字符串DP,区间DP)
    【BZOJ 4305】 4305: 数列的GCD (数论)
    【UOJ 179】 #179. 线性规划 (单纯形法)
    【BZOJ 4568】 4568: [Scoi2016]幸运数字 (线性基+树链剖分+线段树)
    【BZOJ 4027】 4027: [HEOI2015]兔子与樱花 (贪心)
  • 原文地址:https://www.cnblogs.com/zk995/p/10430950.html
Copyright © 2020-2023  润新知