JS--作用域闭包

一、什么是闭包

定义:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

首先我们来解释一下词法作用域
词法作用域就是函数和变量的作用域由代码书写的时候就决定了。比如js函数中定义的变量,只能在该函数作用域范围内访问。js大部分情况都遵循词法作用域。

理解了词法作用域我们通过一个例子套用一下闭包的定义:
根据词法作用域规则,函数bar()的作用域在写代码的时候就已经确定了,显然bar()涵盖了foo()函数的所有作用域,既能访问到foo()函数中的变量a,也可以访问到foo()函数所在的全局作用域中的变量b,这种现象就像函数bar()具有一个涵盖foo()作用域的闭包。
在下列代码中,我们在全局作用域访问bar()函数的引用baz,依然可以找到词法作用域生成时访问到的一切变量,比如a,常规情况下全局作用域是访问不到foo内部的变量a,现在能访问到,这就是闭包带来的效果。

var b = 2;
function foo() {
    var a = 3;
    function bar() {
        console.log(a)
    }
    return bar;
}

let baz = foo();
baz();

通常情况下foo函数在执行完毕后就会被垃圾回收机制销毁foo的内部作用域,因为通常情况下函数执行完毕不会再次被使用。
但是闭包阻止了这种情况的发生,因为bar()函数还在持有对foo()内部作用域的引用,这个引用就是闭包。

二、示例

function foo(){
    var a = 3;
    function bar(){
        console.log(a);//3
    }
    baz(bar)
}
function baz(fn){
    fn();//这就是闭包,在词法作用域之外调用,并且依然持有对词法作用域的引用,持有对foo()的闭包
}

三、总结:

无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论在何处执行这个函数都会使用闭包。

参考文档:《你不知道的JavaScript(上卷)》

你可能感兴趣的:(JS--作用域闭包)