1、 闭包
- 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
- 闭包是嵌套的内部函数、包含被引用变量(函数)对对象,闭包存在于嵌套的内部函数中
- 产生条件:函数嵌套、内部函数引用了外部函数的数据(变量、函数)
function fn1 (){
var a = 2
var b = 'abc'
// 如果是下面这种函数定义定义方式【通过function定义(声明)的函数】,开始执行函数体就已经产生闭包(原因是变量提升)
function fn2(){
//执行函数定义就会产生闭包(不需要非得调用内部函数【子函数】,但是需要调用外部函数【父函数】,要不然不会执行内部函数定义)
console.log(a)
}
}
fn1() //
function fn1 (){
var a = 2
var b = 'abc'
// 如果是下面这种函数定义定义方式【表达式定义声明函数】,在执行到var b = 'abc'时还不会产生闭包(原因是变量提升)
var fn2 = function (){
//执行函数定义就会产生闭包(不需要非得调用内部函数【子函数】,但是需要调用外部函数【父函数】,要不然不会执行内部函数定义)
console.log(a)
}
}
fn1() //
function fn1 (){
function fn2(){
}
}
fn1() //没有产生闭包,因为内部函数没有引用外部函数的变量
2、 常见闭包
function fn1 (){
var a = 2
function fn2(){
a
console.log(a)
}
return fn2
}
var f = fn1() //将fn2赋值给f
f() //3
f() //4 //实际上执行的是fn2,在执行fn1的时候a出现(虽然作为局部变量,但是f()调用的是fn2,所以a并没有消失)
//整个过程只产生了一次闭包,fn()是调用执行函数,不是创建函数(执行函数定义),如果想产生多个闭包,可以多次调用外部函数,调用几次外部函数就产生几个闭包
function showdeloy(msg,time){
settimeout( function(){
alert(msg) },time )
}
showdeloy('atguigu',2000)
//产生了一个闭包
// 首先有外部函数 function showdeloy(msg,time){ }
// 其次有内部函数 function(){ alert(msg)}
// 然后内部函数引用了外部函数的变量 msg 故产生了闭包,(闭包里只有msg,没有time,闭包对象里面只有被引用的变量)