閉包

關(guān)鍵詞:閉包(closure)

概念:
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),對于js,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。

在了解閉包之前,首先我們了解一下作用域鏈(scope chain),每次定義一個函數(shù),都會產(chǎn)生一個作用域鏈。當(dāng)JavaScript尋找變量varible時(這個過程稱為變量解析),總會優(yōu)先在當(dāng)前作用域鏈的第一個對象中查找屬性varible ,如果找到,則直接使用這個屬性;否則,繼續(xù)查找下一個對象的是否存在這個屬性;這個過程會持續(xù)直至找到這個屬性或者最終未找到引發(fā)錯誤為止,下面看例子:

  var s = 11
    function outer(){
        var a = 22;
        function inner(){
            var b = 33;
            console.log(a);
        }
        console.log(s);
        // console.log(b); // undefined 報(bào)錯
        return inner;
    }
  outer(); // 11
  var sss = outer(); //11
  sss(); //22

這就是作用域鏈的訪問關(guān)系,內(nèi)部可以訪問外部,外部不能訪問內(nèi)部;

閉包的優(yōu)點(diǎn)

  • 不產(chǎn)生全局變量,不會對全局造成污染;
  • 可以讓變量永駐內(nèi)存,不會被內(nèi)存回收機(jī)制回收
  • 一些高級應(yīng)用方法要靠閉包實(shí)現(xiàn)
var sss = (function(){
    var a = 1;
    function aaa(){
        a++;
        console.log(a);
    }
    function bbb(){
        a++;
        console.log(a);
    }
    function ccc(){
        a++;
        console.log(a);
    }
    return {
        a:aaa,
        b:bbb,
        c:ccc
    }
})();

//sss();  // 報(bào)錯
sss.a();  //2
sss.b();  //3
sss.c();  //4

以上的例子每次被引用一次,a的值都會累加一次。
通過這種方式,我們定義了一個局部變量能夠被多個函數(shù)引用,且不產(chǎn)生全局污染,這樣我們就形成了一個閉包。


閉包的寫法

    //第1種寫法
    function Circle(r) {
        this.r = r;
    }
    Circle.PI = 3.14159;
    Circle.prototype.area = function() {
        return Circle.PI * this.r * this.r;
    };

    var c = new Circle(3.0);    // 變量c訪問了circle的內(nèi)部函數(shù)
    alert(c.area());
    // 這種寫法沒什么特別的,只是給函數(shù)添加一些屬性。

    //第2種寫法
    var Circle = function() {
        var obj = new Object();
        obj.PI = 3.14159;

        obj.area = function( r ) {
            return this.PI * r * r;
        };
        return obj;
    };
    var c = new Circle();
    alert( c.area( 1.0 ) );
   // 這種寫法是聲明一個變量,將一個函數(shù)當(dāng)作值賦給變量。

    //第3種寫法
    var Circle = new Object();
    Circle.PI = 3.14159;
    Circle.Area = function( r ) {
        return this.PI * r * r;
    };

    alert( Circle.Area( 1.0 ) );
    // 這種方法最好理解,就是new 一個對象,然后給對象添加屬性和方法。

    //第4種寫法
    var Circle={
        "PI":3.14159,
        "area":function(r){
            return this.PI * r * r;
        }
    };
    alert( Circle.area(1.0) );
    // 這種方法使用較多,也最為方便。var obj = {}就是聲明一個空的對象。

閉包的函數(shù)傳參

有時候我們想給事件添加一些參數(shù),就可以用閉包的方式實(shí)現(xiàn)

    function move(speed) {
        return function() {
            box.style.left = box.offsetLeft + speed + "px";
        }
    }
    btn1.onclick = move(125);
    btn2.onclick = move(-125);

閉包的缺點(diǎn)
由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
* btn1.onclick =null;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 作用域和閉包是 JavaScript 最重要的概念之一,想要進(jìn)一步學(xué)習(xí) JavaScript,就必須理解 Java...
    劼哥stone閱讀 1,198評論 1 13
  • ● 閉包基礎(chǔ) ● 閉包作用 ● 閉包經(jīng)典例子 ● 閉包應(yīng)用 ● 閉包缺點(diǎn) ● 參考資料 1、閉包基礎(chǔ) 作用域和作...
    lzyuan閱讀 960評論 0 0
  • 閉包(closure)是Javascript語言的一個難點(diǎn),也是它的特色,很多高級應(yīng)用都要依靠閉包實(shí)現(xiàn)。 一、變量...
    zock閱讀 1,084評論 2 6
  • 閉包(closure)是Javascript語言的一個難點(diǎn),也是它的特色,很多高級應(yīng)用都要依靠閉包實(shí)現(xiàn)。 一、變量...
    zouCode閱讀 1,284評論 0 13
  • 為什么我不關(guān)心具體的大公司,而關(guān)心趨勢? 比如40年前,我們并不知道電腦將會發(fā)生翻天覆地的變化,價格會變得越...
    閱讀 303評論 0 0