2018-04-30 关于闭包

什么是回调函数

A函数作为B函数的参数,并在B函数中执行,A函数就是回调函数。

function setTimer(fn, timer) {
    fn(timer);
}

//function timer就是function setTimer的回调函数
setTimer(function timer(time) {
    console.log(time);
}, 1000);

回调函数也分同步和异步,上例就是同步,而像setTimeout,setInterval中这种牵扯到消息队列(异步队列),Event Loop的回调函数来说,就是异步。

什么是闭包

“A函数中包含B函数,并返回B函数,调用B函数可以使用A函数作用域中定义的变量”,B函数就是闭包,示例如下:

function foo() {
    let _name = "Gary";
    function bar() {
        console.log(`name: ${_name}`);
    }
    return bar;
}
//foo函数执行之后,作用域会被销毁,随之而然的作用域中定义的变量应该会被销毁,并被引擎垃圾回收机制回收,
//但是在这里神奇的事情发生了,foo函数作用域并没有被销毁之后回收,而是还存在于内存中,并被bar使用,这里就形成了闭包。
let bar = foo();
bar();

还有一种形式是这样

function foo() {
    let _name = "Gary";
    function bar() {
        console.log(`name: ${_name}`);
    }
    baz(bar);
}

//这里在foo函数执行之后,按理来说,foo函数中作用域,以及其中_name变量,都会被销毁,并随后被引擎垃圾回收机制回收。
//但是神奇的是,这里的作用域并没有被销毁,而其中的_name变量也没有被销毁,当然也没有被引擎垃圾回收机制回收,而还是存储于内存中,并被bar使用,这里就形成了闭包。
function baz(fn) {
    fn();
}

foo();