闭包是什么
javaScript允许使用内部函数—即函数定义和函数表达式位于另一个函数的内部,这些内部函数可以访问它们所在的外部函数中声名的所有变量、参数和内部函数,当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
闭包指有权访问另一方函数作用域内的变量的函数。
形成闭包的原因
内部的函数存在外部作用域的引用就会导致闭包
闭包的使用场景
- return 回一个函数
var n = 10;
function fn() {
var n = 20;
function f() {
n++;
console.log(n);
}
return f
}
var x = fn();
x() //21
- 函数作为参数
var a = '小明';
function foo(){
var a = 'foo';
function fo(){
console.log(a);
}
return fo
}
function fn(p){
var a = 'fn';
p();
}
fn(foo()) //foo
使用 return fo 返回回来,fo() 就是闭包,f(foo()) 执行的参数就是函数 fo,因为 fo() 中的 a 的上级作用域就是函数foo(),所以输出就是foo
- 3.自执行函数(IIFE)
var n = 100;
(function p(){
console.log(n)
})()
//100
产生了闭包p(),存在 window下的引用 n
- 4.循环赋值
for(var i = 0; i<10; i++){
(function(j){
setTimeout(function(){
console.log(j)
}, 1000)
})(i)
}
因为存在闭包的原因上面能依次输出1~10,闭包形成了10个互不干扰的私有作用域。将外层的自执行函数去掉后就不存在外部作用域的引用了,输出的结果就是连续的 10。为什么会连续输出10,因为 JS 是单线程的遇到异步的代码不会先执行(会入栈),等到同步的代码执行完 i++ 到 10时,异步代码才开始执行此时的 i=10 输出的都是 10。