成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

閉包

Jokcy / 2230人閱讀

摘要:閉包,獲取一個(gè)局部作用域里變量的訪問權(quán)限,涉及到作用域棧執(zhí)行上下文垃圾回收機(jī)制內(nèi)存駐留以及性能問題,閉包切斷作用域棧產(chǎn)生的垃圾回收事件,實(shí)現(xiàn)變量的內(nèi)存駐留。因而,為避免產(chǎn)生嚴(yán)重的性能問題,在完成事件任務(wù)后要把閉包置為,釋放內(nèi)存。

閉包,獲取一個(gè)局部作用域里變量的訪問權(quán)限,涉及到作用域棧、執(zhí)行上下文、垃圾回收機(jī)制、內(nèi)存駐留以及性能問題,閉包切斷作用域棧產(chǎn)生的垃圾回收事件,實(shí)現(xiàn)變量的內(nèi)存駐留。主要應(yīng)用場(chǎng)景在需要累積效應(yīng)、重復(fù)循環(huán)事件、前后事件相關(guān)等。因而,為避免產(chǎn)生嚴(yán)重的性能問題,在完成事件任務(wù)后要把閉包置為null,釋放內(nèi)存。

這里介紹JS中作用域棧的特性,即先進(jìn)后出,全局作用域位于棧底,局部作用域按照編譯、執(zhí)行順序依次入棧,執(zhí)行完畢依次出棧,對(duì)變量進(jìn)行垃圾回收,釋放內(nèi)存。了解此特性,利用全局作用域始終位于棧底,并且總是最后完成垃圾回收,只要在局部作用域中裝載具有全局效應(yīng)的作用域,阻斷垃圾回收,就完成了閉包的設(shè)計(jì)。

示例1

function foo(x) {
    var tmp = 3;
    return function (y) {
        console.log(x + y + tmp);
        x.memb = x.memb ? x.memb + 1 : 1;
        console.log(x.memb);
    }
}
var age = new Number(2);
var bar = foo(age); // bar 現(xiàn)在是一個(gè)引用了age的閉包
bar(10);

示例2

function foo(x) {
    var temp = 3;
    return function (y) {
        console.log(x + y + (++temp));
    }
}
var bar = foo(2);
bar(10);

示例3

function badClosureExample() {
    var as = document.querySelectorAll("a");
    for (var i = 0; i < 4; i++) {
        as[i].onclick = new popNum(i);
        function popNum(oNum) {
            return function () {
                alert("單擊第" + oNum + "個(gè)");
            }
        }
    }
}
badClosureExample();

示例4

 function badClosureExample() {
    var as = document.querySelectorAll("a");
    for (var i = 0; i < 4; i++) {
        (function (i) {
            as[i].onclick = function () {
                alert("單擊第" + i + "個(gè)");
            }
        })(i);
    }
}
badClosureExample();

1、將變量 i 保存給在每個(gè)段落對(duì)象(p)上

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        pAry[i].i = i;
        pAry[i].onclick = function () {
            alert(this.i);
        }
    }
}
init();

2、將變量 i 保存在匿名函數(shù)自身

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        (pAry[i].onclick = function () {
            alert(arguments.callee.i);
        }).i = i;
    }
}
init();

3、加一層閉包,i 以函數(shù)參數(shù)形式傳遞給內(nèi)層函數(shù)

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        (function (i) {
            pAry[i].onclick = function () {
                alert(i);
            }
        })(i);//調(diào)用時(shí)參數(shù)
    }
}
init();

4、加一層閉包,i 以局部變量形式傳遞給內(nèi)層函數(shù)

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        (function () {
            var index = i;//調(diào)用時(shí)局部變量
            pAry[i].onclick = function () {
                alert(index);
            }
        })();
    }
}
init();

5、加一層閉包,返回一個(gè)函數(shù)作為響應(yīng)事件(注意與3的細(xì)微區(qū)別)

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        pAry[i].onclick = function (i) {
            return function () { //返回一個(gè)函數(shù)
                alert(i);
            }
        }(i)
    }
}
init();

6、用Function實(shí)現(xiàn),實(shí)際上每產(chǎn)生一個(gè)函數(shù)實(shí)例就會(huì)產(chǎn)生一個(gè)閉包

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        pAry[i].onclick = new Function("alert(" + i + ")");
        //new一次就產(chǎn)生一個(gè)函數(shù)實(shí)例
    }
}
init();

7、用Function實(shí)現(xiàn),注意與6的區(qū)別

function init() {
    var pAry = document.getElementsByTagName("p");
    for (var i = 0; i < pAry.length; i++) {
        pAry[i].onclick =Function("alert(" + i + ")");
    }
}
init();

示例5

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function () {
        return function () {
            return this.name;
        };
    }
};
alert(object.getNameFunc()()); //The Window

示例6

function outerFun() {
    var a = 0;

    function innerFun() {
        a++;
        alert(a);
    }

    return innerFun; //注意這里
}
var obj = outerFun();
obj(); //結(jié)果為1
obj(); //結(jié)果為2

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82405.html

相關(guān)文章

  • JS 中的閉包是什么?

    摘要:大名鼎鼎的閉包面試必問。閉包的作用是什么。看到閉包在哪了嗎閉包到底是什么五年前,我也被這個(gè)問題困擾,于是去搜了并總結(jié)下來。關(guān)于閉包的謠言閉包會(huì)造成內(nèi)存泄露錯(cuò)。閉包里面的變量明明就是我們需要的變量,憑什么說是內(nèi)存泄露這個(gè)謠言是如何來的因?yàn)椤? 本文為饑人谷講師方方原創(chuàng)文章,首發(fā)于 前端學(xué)習(xí)指南。 大名鼎鼎的閉包!面試必問。請(qǐng)用自己的話簡(jiǎn)述 什么是「閉包」。 「閉包」的作用是什么。 首先...

    Enlightenment 評(píng)論0 收藏0
  • 閉包,又見閉包。。。。?

    摘要:完美的閉包,對(duì),閉包就這么簡(jiǎn)單。這僅僅是閉包的一部分,閉包利用函數(shù)作用域達(dá)到了訪問外層變量的目的。此時(shí)一個(gè)完整的閉包實(shí)現(xiàn)了,的垃圾回收機(jī)制由于閉包的存在無法銷毀變量。 1.閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。 上面這段話來自 javascript 高級(jí)程序設(shè)計(jì) 第三版 P178 。作者說閉包是一個(gè)函數(shù),它有訪問另一個(gè)函數(shù)作用域中的變量的能力。 2.函數(shù)訪問它被創(chuàng)建時(shí)所處的...

    keelii 評(píng)論0 收藏0
  • 多層級(jí)理解閉包

    摘要:第二梯隊(duì)理解有了第一梯隊(duì)的認(rèn)識(shí),我們慢慢修正大腦中對(duì)閉包的認(rèn)識(shí)。理解這句話就可以很好的與閉包這兩個(gè)字關(guān)聯(lián)起來理解閉包這個(gè)概念了。總結(jié)第二梯隊(duì)理解閉包是一個(gè)有特定功能的函數(shù)。第四梯隊(duì)理解閉包通過訪問外部變量,一個(gè)閉包可以維持這些變量。 閉包 閉包的概念困惑了我很久,記得當(dāng)時(shí)我面試的時(shí)候最后一面有一個(gè)問題就是問題關(guān)于閉包的問題,然而到現(xiàn)在已經(jīng)完全不記得當(dāng)時(shí)的題目是啥了,但仍然能夠回憶起當(dāng)時(shí)...

    nemo 評(píng)論0 收藏0
  • 面試官問我:什么是JavaScript閉包,我該如何回答

    摘要:到底什么是閉包這個(gè)問題在面試是時(shí)候經(jīng)常都會(huì)被問,很多小白一聽就懵逼了,不知道如何回答好。上面這么說閉包是一種特殊的對(duì)象。閉包的注意事項(xiàng)通常,函數(shù)的作用域及其所有變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷毀。從而使用閉包模塊化代碼,減少全局變量的污染。 閉包,有人說它是一種設(shè)計(jì)理念,有人說所有的函數(shù)都是閉包。到底什么是閉包?這個(gè)問題在面試是時(shí)候經(jīng)常都會(huì)被問,很多小白一聽就懵逼了,不知道如何回答好。這個(gè)...

    BenCHou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<