JS匿名自执行函数(IIFE)

    JS自执行函数又称为IIFE,在我们开发过程中会使用到大量的自执行函数。

IIFE写法:

    使用建议:在使用只执行函数前面加上 “ ; ”,避免压缩或者打包时变为函数。

    首先我们要了解一般情况下什么是函数声明语句,什么是函数表达式语句,以便于接下来的实验。

    辨别方法:以“function”开头的有名称的函数是函数声明语句。

function a();//函数声明语句

var a = function();//函数表达式语句

    下面我们在分析一道面试题:

var a = function(){}

var b = function(){}

console.log(a()+b());//输出结果是NaN

因为解释器会把前面的a()认为是一个语句块的结束,后面的‘+’一元运算符有把后面b()转换为数字这么一个功能,所以得到的结果是NaN。

因此我们在做自执行函数的时候,要把函数的声明变为函数表达式,这样就不会影响输出的结果了。

方法1:

(function(){

})();

方法2:

(function(){

}() );

方法3(通过操作符):但是这种方法仍然会占用命名空间,所以不建议使用。

var a = function (){

console.log(2)

}()

方法4(通过操作符)与或操作符:

false || function (){

console.log(2)

}()

true && function (){

console.log(2)

}()

0 , function (){

console.log(2)

}()

注:通过操作符实现自执行函数一般使用在打包工具里面,比如webpack打包后会经常看到 ” 0,functtion(){}()“

方法5:(一元运算符)一元运算符仍然可以将函数声明转换为函数表达式,在bootstrap框架中常用。

! function (){

console.log(2)

}()

-function (){

console.log(2)

}()

+function (){

console.log(2)

}()

方法6:new一个匿名函数,后面可省略括号。(不建议使用,会产生争议)

new function (){

console.log(2)

};//在不传参的情况下使用new也可以自执行,可以去掉小括号,不常用。


以上方法性能比较:

除了一元运算符的时候性能偏低,因为要进行一次数字类型的转换,其他的都可以。


应用:

我们要了解,为什么使用自执行函数,确切的说是自执行函数的优点以及缺点:

        1.避免作用域命名污染

        2.提升性能(减少了对作用域的查找)

        3.避免全局命名冲突

                比如jq里面暴露给全局作用域$和query两个变量,为了解决这个问题,我们可以将window.jq作为一个实参传递给一个立即执行的匿名函数。这样的话,我们再次命名$或者query就不会有冲突了。

        4.有利于代码压缩(可以用简单字符串代替)

        5.保存闭包状态

        6.颠倒代码执行顺序

(function(){})(bb())

console.log(12)

function bb(){

        console.log(22)

};//打印顺序是22,12

这就叫做UMD通用模块规范,在实际开发过程中被广泛应用。

        7.模仿块级作用域

    作用域的内部可以访问到外部,外部不可以访问到内部,js作用域的缺陷就是没有块级作用域。

    比如:

            for (var i = 0; i <6; i++) {

            }

            console.log(i);//打印出来的是6,在for循环外面仍然可以访问到变量i。

三个特殊的语句可以欺骗语法分析:


        evel(); //内部存放js代码可被执行

        with(object instance)   {           //代码块   }  ; // with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。

        try {   // 此处是可能产生例外的语句   } catch(error) {  // 此处是负责例外处理的语句   } finally {   // 此处是出口语句   }


所以在ES3下,严格来说js是没有块级作用域的,但是以上三种方法可以实现块级作用域的效果。

常用的有try catch,把要声明的变量放在try里面,然后当一个错误抛出,让cath接住使用。缺点:1.多个块级作用域需要多个嵌套;2.性能问题。

匿名自执行函数只能模拟块级作用域,并非真正的作用域。

   let定义的作用域是块级作用域,但不要轻易使用,针对开发场景来选择。

        8.填坑(加载第三方插件时候的一些问题)

                比如有个人写了这样一段代码:undefined=true,再早之前undefined是可以被赋值的,所以这段代码不会报错,但是这样会致使你下面的一些判断出错

                这时候如果使用匿名自执行函数就可以解决:

(function(undefined){

        console.log(undefined)

}())

了解他的优点之后我们才可以在正确的场景使用IIFE。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 9,700评论 0 13
  • 函数声明和函数表达式有什么区别 (*)解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;函数表达式则必须...
    coolheadedY阅读 2,994评论 0 1
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 12,385评论 2 17
  • 早安亲爱的小伙伴!貌似最近更多在分享我走过的地方、做过的事情、听过的故事,根据小伙伴的回应和简书后台阅读量...
    黄疍疍阅读 2,910评论 1 1
  • 无论怎样挣扎 或者多么顺畅 生命总是在不知不觉间往前流逝 渐渐 曾经的激情变平淡 曾经的执着变平常 曾经的骄傲变平...
    梁木子阅读 1,358评论 1 1