成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

我來(lái)給Javascript中的閉包下個(gè)定義

MadPecker / 418人閱讀

摘要:注意由定義可以知道,閉包函數(shù)肯定是定義在函數(shù)中,才可能有上級(jí)的函數(shù)作用域可以訪問(wèn),否則上級(jí)作用域就是全局作用域。造成這種結(jié)果的原因就是綁定的多個(gè)函數(shù)是閉包函數(shù),他們共同使用保留的上級(jí)函數(shù)作用域中的變量。

1 閉包的定義

維持了自由變量不被釋放的函數(shù), 稱為閉包,(自由變量指不在自身上下文,也不在全局上下文中的變量)。

那么閉包函數(shù)的特點(diǎn)在哪里,我們知道函數(shù)在創(chuàng)建的時(shí)候,它的[[scope]]屬性就已經(jīng)確定并不可以改變,所以閉包函數(shù)在創(chuàng)建的時(shí)候就保存了上級(jí)的作用域鏈,閉包函數(shù)通過(guò)作用域鏈去尋找使用到的變量,正常情況下,函數(shù)在執(zhí)行完畢后,將銷毀函數(shù)的執(zhí)行上下文,但是由于閉包函數(shù)的存在,包含閉包函數(shù)的上級(jí)函數(shù)執(zhí)行完畢后,如果閉包函數(shù)還存在,那么這個(gè)上級(jí)函數(shù)的作用域中的變量仍然保留在內(nèi)存中供閉包函數(shù)訪問(wèn)。

注意:
由定義可以知道,閉包函數(shù)肯定是定義在函數(shù)中,才可能有上級(jí)的函數(shù)作用域可以訪問(wèn),否則上級(jí)作用域就是全局作用域。全局作用域中的變量本身就一直在內(nèi)存中,所以訪問(wèn)全局作用域中變量的函數(shù)不能稱為閉包。

var name = "global";   
function func1() {
    var name1 = "func1";
    console.log(name);
    console.log(name);
    function func2() {
        console.log(name);
        var name2 = "func2";
        function func3() {
            console.log(name2);
        }
        func3();
    }
    func2();
}
func1();

上面代碼中,func3為閉包函數(shù),因?yàn)樗L問(wèn)了上級(jí)函數(shù)作用域中的變量name2,func2不能稱為閉包函數(shù),因?yàn)樗鼈冊(cè)L問(wèn)的是全局作用域中的變量name。

2 常見(jiàn)的閉包場(chǎng)景 2.1 維持變量的閉包
var person = (function(){
    var _name = "yangyiliang";
    var _age = 18;
    return {
        getName: function () {
            return _name;
        },
        getAge: function () {
            return _age;
        },
        addAge: function (num) {
            return _age += num;
        },
        reduceAge: function (num) {
            return _age -= num;
        }
    }
})();
 
console.log(person.addAge(5)); // 23
console.log(person.reduceAge(3)); //20

上面的代碼中,首先外層包裹了一個(gè)匿名立即執(zhí)行函數(shù),創(chuàng)造了一個(gè)上級(jí)函數(shù)作用域,getName和getAge方法都是在其內(nèi)部,并且訪問(wèn)了上級(jí)函數(shù)作用域中的變量,所以是閉包,所當(dāng)匿名函數(shù)執(zhí)行完畢后,本該銷毀的執(zhí)行上下文,卻因?yàn)殚]包函數(shù)而保留了作用域中的_name和 _age變量, 通過(guò)addAge 和reduceAge的結(jié)果發(fā)現(xiàn),兩個(gè)閉包共用保留的作用域。

2.2 維持參數(shù)的閉包
function makeSizer(size) {
    return function() {
        document.body.style.fontSize = size + "px";
    };
}
 
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
 
document.getElementById("size-12").onclick = size12;
document.getElementById("size-14").onclick = size14;
document.getElementById("size-16").onclick = size16;

上面的代碼中,makerSizer函數(shù)的返回值即為閉包函數(shù),閉包函數(shù)訪問(wèn)上級(jí)函數(shù)作用域中的參數(shù)。
2.3 循環(huán)創(chuàng)建閉包常見(jiàn)錯(cuò)誤

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

上面的代碼中,假設(shè)arr的length為5,想要實(shí)現(xiàn)的功能是點(diǎn)擊5個(gè)P標(biāo)簽分別alert 0,1,2,3,4。但是事實(shí)上得到的結(jié)果卻是都alert 5。

造成這種結(jié)果的原因就是綁定的多個(gè)onclick函數(shù)是閉包函數(shù),他們共同使用保留的上級(jí)函數(shù)作用域中的變量 i 。 for循環(huán)執(zhí)行結(jié)束后 i 的值即為5。

要想解決這種錯(cuò)誤,就讓這些閉包保存不同的上級(jí)作用域即可。

function bind() {
    var arr = document.getElementsByTagName("p");
    for(var i = 0; i < arr.length;i++){
        (function (i) {
            arr[i].onclick = function(){
            alert(i);
            }
        })(i);
    }
}  
bind();
或者
function bind() {
    var arr = document.getElementsByTagName("p");
    for(var i = 0; i < arr.length;i++){
        arr[i].onclick = (function(i){
            return function () {
                alert(i);
            }
        })(i);
    }
}  
bind();

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/88064.html

相關(guān)文章

  • 重名就會(huì)被覆蓋?那JavaScript中是如何實(shí)現(xiàn)重載的呢?

    摘要:但是我們知道中是沒(méi)有重載的為什么沒(méi)重載不是的特性也會(huì)有的嗎,因?yàn)楹竺娑x的函數(shù)會(huì)覆蓋前面的同名函數(shù),但是重載那么好用,我們想在實(shí)現(xiàn)函數(shù)重載該怎么辦呢今天就來(lái)給大家講講在里面實(shí)現(xiàn)函數(shù)重載的兩個(gè)思路。這就是閉包的核心作用。 大家都知道,所謂重載,就是一組相同的函數(shù)名,有不同個(gè)數(shù)的參數(shù),在使用時(shí)調(diào)用一個(gè)函數(shù)名,傳入不同參數(shù),根據(jù)你的參數(shù)個(gè)數(shù),來(lái)決定使用不同的函數(shù)!重載這個(gè)在JAVA這些經(jīng)典的...

    mozillazg 評(píng)論0 收藏0
  • 什么是閉包

    大家好:今天我們來(lái)徹底了解下什么是閉包:首先我們先看一個(gè)例子: var local =1; function a(){ console.log(local); }; 首先我來(lái)給大家介紹下:假設(shè)下如果上述代碼在一個(gè)立即執(zhí)行的函數(shù)中;那么變量local就是一個(gè)局部變量,有一個(gè)函數(shù)a,a可以訪問(wèn)到局部變量local;好了上述這個(gè)就是個(gè)閉包;在網(wǎng)上有許多介紹閉包的概念,如函數(shù)中嵌套一個(gè)函數(shù),然后將...

    canger 評(píng)論0 收藏0
  • JavaScript - 收藏集 - 掘金

    摘要:插件開(kāi)發(fā)前端掘金作者原文地址譯者插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡(jiǎn)單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內(nèi)優(yōu)雅的實(shí)現(xiàn)文件分片斷點(diǎn)續(xù)傳。 Vue.js 插件開(kāi)發(fā) - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡(jiǎn)單的方式。插....

    izhuhaodev 評(píng)論0 收藏0
  • 使用JavaScript閉包遇到的陷阱(一)

    摘要:使用閉包遇到的陷阱一陷阱在類的原型對(duì)象中添加特權(quán)方法首先定義一個(gè)類,該類中有一個(gè)私有變量定義個(gè)特權(quán)方法來(lái)訪問(wèn)修改私有變量然后我們對(duì)類進(jìn)行測(cè)試到目前為止,類正常工作。 使用JavaScript閉包遇到的陷阱(一) 陷阱:在類的原型對(duì)象中添加特權(quán)方法 首先定義一個(gè)Page類,該類中有一個(gè)私有變量dom: function Page(){ var dom; } 定義2個(gè)特權(quán)方法來(lái)訪問(wèn)...

    caohaoyu 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式系列二:?jiǎn)卫J?/b>

    摘要:什么時(shí)候需要用到單例模式呢其實(shí)單例模式在日常開(kāi)發(fā)中的使用非常的廣泛,例如各種浮窗像登錄浮窗等,無(wú)論我們點(diǎn)擊多少次,都是同一個(gè)浮窗,浮窗從始至終只創(chuàng)建了一次。這種場(chǎng)景就十分適合運(yùn)用單例模式。 單例模式 什么是單例模式? 單例模式的定義:一個(gè)類僅有一個(gè)實(shí)例,并且可以在全局訪問(wèn)。什么時(shí)候需要用到單例模式呢?其實(shí)單例模式在日常開(kāi)發(fā)中的使用非常的廣泛,例如各種浮窗、像登錄浮窗等,無(wú)論我們點(diǎn)擊多少...

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

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

0條評(píng)論

閱讀需要支付1元查看
<