JavaScript教程:避免使用全局变量-IIFE立即执行函数(自执行函数、立即执行函数、自启动函数、自调用函数)

提出问题

在代码较多时,需要定义很多变量,可能会有同名的情况,这样就出bug了,如下:

var name = '李雷'
var name2 = '韩梅梅'
var name3 = 'lucy'

var name = 'lili' // 此时出现bug,与第一个变量name同名了

为什么避免使用全局变量

.js 文件中定义的全局变量,都是在全局作用域中

一个 .js 文件中声明的 变量 或 函数,在另一个 .js 文件中是可以访问的

同时也会产生 命名冲突,如:5个前端程序员,在当前项目中创建5个 .js 文件,如果都声明全局变量 book 或 函数 Person,就会导致 bug

类比

相当于把 海王关在小屋里,他只会对自己的对象下手,不会干扰别的屋子的对象

解决

使用自调用函数

IIFE立即执行函数

IIFE(Immediately Invoked Functions Expressions),立即执行函数,无需借助其他函数或方法来启动

将 变量、函数 定义在该 IIFE函数内

作用域

IIFE立即执行函数中,所有 变量 和 方法 都是 局部作用域 内的,即:只能在IIFE立即执行函数内访问。

想要设置成 全局作用域供外部访问 ,可以在函数体内设置 window.fn=fn;

实现原理

函数表达式

立即执行函数主要是使用 函数表达式,如下:

var  sayHello  =  function ( name )  { 
  console . log ( 'Hello '  + name ) ; 
} 
console.log(sayHello);

此时打印出 函数对象,而没有调用该函数

让函数表达式立即执行

如果想要直接调用,需要加上 ():

var  sayHello  =  function ( name )  { 
  console . log ( 'Hello '  + name ) ; 
}('李雷')

此时该函数就立即执行了

简化名字(会报错)

由于是立即执行,没必要加上名字,但去掉名字会报错:

function ( name )  { 
  console.log( 'Hello '  + name ) ; 
}('李雷')

因为JavaScript引擎在解析代码的时候,发现 function 作为开头,引擎会认为现在要创建函数,但没有发现函数名称,于是无法正确理解这段代码

简化名字(解决)

所以要告诉JavaScript 引擎说,这不是 function 命令。要达到这样的目的,我们要让引擎在解析代码的时候,不是以读到function 作为开头。

为了要达到这样的目的,我们最常使用的做法就是用括号 () 将 function(){ ...} 包起来,像是这样:

(function ( name )  { 
  console.log( 'Hello '  + name ) ;
})

相当于 在括号内放入表达式,例如:(3+2),所以JavaScript就会以表达式的方式来读取这段函数

简化名字后实现立即执行

结合上面的立即执行,最终实现如下:

(function ( name )  { 
  console.log( 'Hello '  + name ) ;
})('李雷')

实现方法

明白上面的实现原理,下面介绍下实现方法,其实实现方法有很多种,这里只列举常见好理解的几种

写法一

定义匿名函数,并用 () 将匿名函数括起来,然后在后面在加上 () 表示调用

注意:多个自启动函数,前面要有 ;,否则报错

(function(形参) {
    // 函数体
})  (实参)

写法二

定义匿名函数,然后在后面在加上 () 表示调用,在外面用 () 括起来

注意:多个自启动函数,前面要有 ;,否则报错

(function(形参) {
    // 函数体
}(实参)   )

写法三

定义匿名函数,然后在后面在加上 () 表示调用
在前面要有 !,可以换作其他运算符或者 void

!function(形参) {
    // 函数体
}(实参)

案例

传统写法

var a = 1
var b = 2
function add(){
    console.log(a+b)
}
add()

打开页面后,控制台打印 3

自调用函数写法一

(function(){
    var a = 1
    var b = 2
    function add(){
        console.log(a+b)
    }
    add()
})()

打开页面后,控制台打印 3

自调用函数写法二

(function(){
    var a = 1
    var b = 2
    function add(){
        console.log(a+b)
    }
    add()
}())

打开页面后,控制台打印 3

自调用函数写法三

!function(){
    var a = 1
    var b = 2
    function add(){
        console.log(a+b)
    }
    add()
}()

打开页面后,控制台打印 3

参考:
https://zhuanlan.zhihu.com/p/74440468


原文出处:/show_1IX3mKNfVufK.html