中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

分析JavaScript閉包特性

發布時間:2021-11-06 15:50:43 來源:億速云 閱讀:182 作者:iii 欄目:web開發

這篇文章主要介紹“分析JavaScript閉包特性”,在日常操作中,相信很多人在分析JavaScript閉包特性問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”分析JavaScript閉包特性”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

首先先簡要總結閉包特性:

· 函數的局部變量在函數返回之后仍然可用

· 棧上的內存空間在函數返回之后仍在存在,不被回收

給個例子。下面這段代碼會返回一個函數的引用:

function sayHello2(name) {

    var text = 'Hello ' + name; // Local variable

    var sayAlert = function() { alert(text); }

    return sayAlert;

}

say2 = sayHello2('Bob');

say2(); // alerts "Hello Bob"

對于這段代碼,C程序員可能會認為sayAlert和say2一樣,都是指向一個函數的指針。但實際上它倆有一個重要區別: 在JavaScript中,你可以認為一個函數的指針變量同時擁有兩個指針。一個指向這個函數,另一個隱藏的指針指向一個閉包。

重點在于你的函數內是否引用的外部變量。

在JavaScript中,如果你在一個函數內定義一個新的函數,那么這個新的函數就是一個閉包。 對于C或者其他高級語言,函數執行結束并返回之后,它所占用的棧空間將被釋放回收。函數內定義的局部變量將不再可用。但在JavaScript中,并不這樣。如上所示,函數執行結束后,它所占用的棧空間并不會被全部回收。

上面是基本理論。更進一步,再來一個例子:

function say667() {

    // Local variable that ends up within closure

    var num = 666;

    var sayAlert = function() { alert(num); }

    num++;

    return sayAlert;

}

var sayNumber = say667();

sayNumber(); // alerts 667

這個例子說明:閉包中使用的函數局部變量并非是值拷貝,而是引用。say667()執行結束之后number所在的那塊內存的值為667,而sayNumber()是在say667()執行結束之后才執行,當它訪問number所在的內存時,結果自然也是667。

再進一步,看看用closure時易發生的錯誤的例子:

function buildList(list) {

    var result = [];

    for (var i = 0; i < list.length; i++) {

        var item = 'item' + list[i];

        result.push( function() {alert(item + ' ' + list[i])} );

    }

    return result;

}

function testList() {

    var fnlist = buildList([1,2,3]);

    // Using j only to help prevent confusion -- could use i.

    for (var j = 0; j < fnlist.length; j++) {

        fnlist[j]();

    }

}

時刻保持清醒:變量是在內存里的,閉包使用的是內存的引用而不是那塊內存的值拷貝。

當你在循環中定義函數(閉包)的時候得小心,它可能并不像你最開始想的那樣工作。關鍵有兩個:

· 子函數使用的是外部函數的局部變量的引用。

· 循環內只是定義了子函數,并沒有執行這個字函數。

最后,來一個最抽象的例子:

function newClosure(someNum, someRef) {

    // Local variables that end up within closure

    var num = someNum;

    var anArray = [1,2,3];

    var ref = someRef;

    return function(x) {

        num += x;

        anArray.push(num);

        alert('num: ' + num +

            '\nanArray ' + anArray.toString() +

            '\nref.someVar ' + ref.someVar);

      }

}

obj = {someVar: 4};

fn1 = newClosure(4, obj);

fn2 = newClosure(5, obj);

fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;

fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;

obj.someVar++;

fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;

fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;

這個例子說明,閉包的創建時機是在函數被調用的時候。每次函數調用都會生成一個新的閉包,也就是一塊新的內存區域。因為函數每次調用都會新分配一塊棧內存,這是一回事。

最后我自己來總結一下閉包:

· 函數的局部變量在其他地方被引用

· 閉包有兩種基本情況:閉包的返回值是一個函數,它其中使用了該閉包的局部變量;閉包內定義了內部函數,內部函數引用了閉包的局部變量

· 每次函數調用,都會生成一個新的閉包,分配新的內存

實例:(滑過tab)

window.onload= function(){

var tits = $('#tabTit1 li');

var cons = $('#tabCon1 .con');

var len = cons.length;

var liChange = function(){

for(var n=0;n<len;n++){

tits[n].className = tits[n].className.replace(/\s*cur/g,'');

cons[n].className = cons[n].className.replace(/\s*cur/g,'');

}

}

for(var i = 0; i<tits.length; i++){

tits[i].i = i;

tits[i].onmouseover = function(){

liChange();

cons[this.i].addClass('cur');

tits[this.i].addClass('cur');

}

}

};

到此,關于“分析JavaScript閉包特性”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

共和县| 宁陵县| 旌德县| 合川市| 曲水县| 红河县| 荔波县| 天台县| 河北区| 犍为县| 海盐县| 华池县| 淮北市| 敦煌市| 商都县| 清新县| 乐亭县| 章丘市| 萨嘎县| 洛隆县| 治多县| 德昌县| 韩城市| 黄平县| 博爱县| 平舆县| 湖南省| 大丰市| 霍林郭勒市| 土默特右旗| 新巴尔虎右旗| 五台县| 五大连池市| 正蓝旗| 临夏市| 营山县| 朝阳市| 甘泉县| 颍上县| 蒙自县| 报价|