如何使用立即执行函数
- 我们不想要全局变量
- 我们要使用局部变量
- ES 5 里面,只有函数有局部变量
- 于是我们声明一个 function xxx,然后 xxx.call()
- 这个时候 xxx 是全局变量(全局函数)
- 所以我们不能给这个函数名字
- function(){}.call()
- 但是 Chrome 报错,语法错误
- 试出来一种方法可以不报错:
- !function(){}.call() (我们不在乎这个匿名函数的返回值,所以加个 ! 取反没关系)
- (function(){}).call() 方方不推荐
xxx (function(){}).call() 报错
- frank192837192463981273912873098127912378.call() 不推荐
如何使用闭包
- 立即执行函数使得 person 无法被外部访问
- 闭包使得匿名函数可以操作 person
- window.frankGrowUp 保存了匿名函数的地址
- 任何地方都可以使用 window.frankGrowUp
=> 任何地方都可以使用 window.frankGrowUp 操作 person,但是不能直接访问 person
立即执行函数配合闭包
- 在一个模块里面使用var声明的变量,在另一个模块中可以使用,因为声明的是全局变量。万一其他模块自己也声明了一个一模一样的变量,就会带来名称覆,导致出问题。
- 解决问题的办法之一是:不要使用全局变量,使用局部变量
- 在ES6之前只有函数里面才有局部变量。
- JS中使用一个花括号包起来是不可以的,因为声明的变量会变量提升的。
- 我们可以使用一个没有名字的函数将这些代码包起来,并立即执行,执行结束之后,里面的局部变量就会消失的
- !function(){}.call()是可以的,但是会改变返回值,我们并不关心返回值
-
使用(function(){}).call()也是可以的,但是当前面有一个东西。如xxx(function(){}).call(),整个语法就乱了
image.png - 如果你想创建一个变量让所有人都可以使用,可以使用window.变量
- 我们还可以使用闭包;如下面这种代码,我们始终不能从外面找到age的所有信息,只能对它进行相应的操作
!function(){ var person = { name: 'frank', age: 18 } window.frankGrowUp = function(){ person.age += 1 return person.age } }.call()
- 只要函数用了外面的变量,那么这个函数以及外面的变量就是闭包。闭包用来隐藏细节。如果不是立即执行函数,那么上面这个就毫无意义。
- 总结一下:
- 立即执行函数使得person无法被外界访问
- 闭包使得匿名函数可以操作person
- window.frankGrowUp保存了匿名函数的地址
- 任何地方都可以使用window.frankGroupUp
- 任何地方都可以使用window.frankGroupUp 操作person,但是不能直接访问person
- 代码
var accessor = function(){ var person = { name: 'frank', age: 18 } return function(){ person.age += 1 return person.age } } // 这边accessoe.call其实就是一个立即执行函数,只不过这个立即执行函数返回的是一个函数 var growUp = accessor.call() growUp.call(
总结
闭包一定要跟立即执行函数一起使用,因为没有立即执行函数,就没有局部变量,闭包就失去了意义