提出问题
在代码较多时,需要定义很多变量,可能会有同名的情况,这样就出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