閉包?反正看完我就懂了

閉包?反正看完我就懂了

想要好好的理解閉包,你得首先理解做用域。別說了,趕忙去看做用域吧,?,這世界就是如此殘酷。好,言歸正傳,咱們是來學習閉包的。O(∩_∩)O閉包

什麼是閉包??

百度了一波,but理解不了哇。別怕,我來幫你。其實,能夠這樣理解的:魔術師的幕後藏着一我的,咱們要揭開他的假裝,假裝以後的那我的是..知道你會說就是閉包了。閉包就是函數定義時的上下文環境。函數

get閉包

說了這麼久,還不上菜,都快要餓死了。學習

菜來了!?

閉包只要記住:code

  • 閉包產生是:函數內嵌套函數;
  • 閉包函數在外面被調用,訪問;
  • 閉包能夠訪問外部的變量,可是外部的變量不能訪問內部;
  • 閉包能夠保持對定義時的做用域的引用,使之不被銷燬,長生不老。

可能你又懵了,不怕,咱用實例來講話。生命週期

實例一:

function foo(){
    var a=2;

    function bar(){
        console.log(a);//2
    }
    bar();
}
foo();

這看起來應該就是閉包吧,不,確切地說它不是。由於bar()嵌套在foo()內部,這裏並無在外面調用bar().作用域

閉包來啦

var func=function(){
    var a=1;
    return function(){
        a++;
        alert(a);
    }
}
var f=func();
f();//閉包哇!

函數f()的詞法做用域可以訪問func()的內部做用域,而後把裏面的匿名函數function()自己看成一個值類型進行傳遞。其實這個閉包的產生過程能夠理解爲在裏面的匿名函數定義時正處於懷孕階段,到外面f()調用時,娃就出生了,娃就是閉包啦。get

不通常的閉包

有時候對函數類型的值進行參數傳遞有不少種方法,可是不要方,當他們在別處被調用時仍然能夠觀察到閉包。
看下面:it

function foo(){
    var a=2;

    function baz(){
        console.log(a);//2
    }
    bar(baz);
}
function bar(fn){
    fn();//媽,閉包又來啦
}

把內部的函數baz傳遞給bar,當調用這個內部函數時(如今叫fn()),它涵蓋的foo()內部做用域就出來了,由於它可以訪問a.io

還有這樣的閉包

function wait(message){
    setTimeout(function timer(){
        console.log(message);
    },1000);
}
wait("Hello,closure!");

將一個內部函數(名爲timer)傳遞給setTimeout(...)。timer具備涵蓋wait(...)做用域的閉包,還保留着對變量message的引用。console

循環和閉包

for(var i=1;i<=5;i++){
    (function(){
        var j=i;
        setTimeout(function trimer(){
            console.log(j);
        },j*1000);
    })();
}

在for循環裏面,咱們在每一個迭代過程當中都建立了一個閉包做用域,且做用域內定義了變量,進行了賦值。閉包改變了變量的生命週期,變量將獲得永生。

小結:

閉包是隱藏在函數裏面卻又很厲害的。相信你已經理解了閉包,那麼恭喜你,從某種意義上得到了重生!
閉包實際上是一種事實,當函數能夠記住並訪問所在的詞法做用域,即便函數是在當前詞法做用域以外執行,這時就產生了閉包。閉包產生以後可以涵蓋它所能訪問的詞法做用域。

好啦,講完啦,若是你們以爲有錯誤或者改進的地方歡迎指出,只求共同進步。?

相關文章
相關標籤/搜索