文章目录
1. 闭包是什么
闭包就是:一个函数,这个函数能够访问其他函数的作用域中的变量
2. 为什么闭包函数能够访问其他函数作用域的变量
- 闭包产生的本质是:在一个函数(外部函数)内部定义的函数(内部函数)会将外部函数作用域中的活动对象添加到自己的作用域链中
- 由于闭包是建立在一个函数内部的子函数,可访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁,故可访问。
3. 为什么其他非闭包的函数没有权限访问另一个函数的内部作用域
因为在JS中,变量的作用域属于函数作用域,在函数执行后作用域就会被清理、内存也随之回收
4. 闭包解决了什么问题
由于闭包可以缓存上级作用域,使得函数外部打破了“函数作用域”的束缚,可以访问函数内部的变量
5. 闭包的应用场景
- 闭包随处可见,一个Ajax请求的成功回调,一个事件绑定的回调方法,一个setTimeout的延时回调,或者一个函数内部返回另一个匿名函数,这些都是闭包。
- 简而言之,无论使用何种方式对函数类型的值进行传递,当函数在别处被调用时都有闭包的身影。
6. 创建闭包的常见的方式
在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
匿名函数和闭包之间没有什么关系,只不过很多时候在用到匿名函数解决问题的时候恰好形成了一个闭包,就导致很多人分不清楚匿名函数和闭包的关系。
这个时候我们就要谈到匿名函数了.
7. 匿名函数
-
匿名函数是一种在运行时动态声明的函数。它们之所以被称为匿名函数是因为不同于普通函数,它们并没有函数名,与之对应的就是有名字的函数,也叫具名函数。
-
匿名函数是通过函数表达式而不是函数声明语法定义的。你可以在任何可以放置表达式的地方利用函数表达式创建一个新函数。
//匿名函数
function (){
console.log('匿名函数');
}
//具名函数
function myFn(){
console.log('具名函数');
}
//变量a就是匿名函数的名字
var a = function(){
console.log('a就是匿名函数的名字');
//如果我们直接在控制台中运行匿名函数,会发现报错,无法执行。
}
8. 立即执行函数
匿名函数是无法执行的,一般用到匿名函数的时候都是立即执行,江湖人称“立即执行函数”
常见立即执行函数写法:
- 首先声明一个匿名函数
function(){
alert('我是匿名函数')
}
- 然后在匿名函数后面接一对括号 (),调用这个匿名函数
(function(){
alert('我是匿名函数')
})()
还要用一个括号把函数包起来的原因,是为了兼容JS的语法,如果我们不加括号,直接写成
function(){
alert('我是匿名函数')
}()
浏览器会报语法错误
9. 立即执行函数的作用
创建一个独立的作用域,在这个作用域里面,外面访问不到,避免变量污染。
举个栗子!
for(var i=0;i<6;i++){
setTimeout(function(){
console.log(i); //输出的总是 6,而不是0,1,2,3,4,5
},i*1000);
}
因为setTimeout里面的执行函数是异步的,执行的时候,i的值是贯穿整个作用域的,而不是单独一个给每个定期器分配了一个i,for运行完的值是6,此时输出就总是6了。
用立即执行函数给每个定时器创造一个独立作用域即可解决
for(var i=0;i<6;i++){
(function(j){
setTimeout(function(){
console.log(j);
},j*1000);
})(i);
}
在for循环执行时,立即执行函数就已经有了结果了。而每个立即执行函数里面的j值就是独立的一个,不会受后面影响。所以会分别执行5次定时器。