在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 閉包和引用
arguments 對(duì)象
類型轉(zhuǎn)換
構(gòu)造函數(shù)
instanceof 操作符
自動(dòng)分號(hào)插入
為什么不要使用 eval
對(duì)象使用和屬性
作用域與命名空間
this 的工作原理
typeof 操作符
相等與比較
閉包和引用
數(shù)組遍歷與屬性
Array 構(gòu)造函數(shù)
原型
hasOwnProperty 函數(shù)
undefined 和 null
函數(shù)聲明與表達(dá)式
setTimeout 和 setInterval
for in 循環(huán)

閉包和引用

閉包是 JavaScript 一個(gè)非常重要的特性,這意味著當(dāng)前作用域總是能夠訪問外部作用域中的變量。 因?yàn)?函數(shù) 是 JavaScript 中唯一擁有自身作用域的結(jié)構(gòu),因此閉包的創(chuàng)建依賴于函數(shù)。

模擬私有變量

    function Counter(start) {
        var count = start;
        return {
            increment: function() {
                count++;
            },

            get: function() {
                return count;
            }
        }
    }

    var foo = Counter(4);
    foo.increment();
    foo.get(); // 5

這里,Counter 函數(shù)返回兩個(gè)閉包,函數(shù) increment 和函數(shù) get。 這兩個(gè)函數(shù)都維持著 對(duì)外部作用域 Counter 的引用,因此總可以訪問此作用域內(nèi)定義的變量 count.

為什么不可以在外部訪問私有變量

因?yàn)?JavaScript 中不可以對(duì)作用域進(jìn)行引用或賦值,因此沒有辦法在外部訪問 count 變量。 唯一的途徑就是通過那兩個(gè)閉包。

    var foo = new Counter(4);
    foo.hack = function() {
        count = 1337;
    };

上面的代碼不會(huì)改變定義在 Counter 作用域中的 count 變量的值,因?yàn)?foo.hack 沒有 定義在那個(gè)作用域內(nèi)。它將會(huì)創(chuàng)建或者覆蓋全局變量 count。

循環(huán)中的閉包

一個(gè)常見的錯(cuò)誤出現(xiàn)在循環(huán)中使用閉包,假設(shè)我們需要在每次循環(huán)中調(diào)用循環(huán)序號(hào)

    for(var i = 0; i < 10; i++) {
        setTimeout(function() {
            console.log(i);  
        }, 1000);
    }

上面的代碼不會(huì)輸出數(shù)字 09,而是會(huì)輸出數(shù)字 10 十次。

當(dāng) console.log 被調(diào)用的時(shí)候,匿名函數(shù)保持對(duì)外部變量 i 的引用,此時(shí) for循環(huán)已經(jīng)結(jié)束, i 的值被修改成了 10.

為了得到想要的結(jié)果,需要在每次循環(huán)中創(chuàng)建變量 i拷貝。

避免引用錯(cuò)誤

為了正確的獲得循環(huán)序號(hào),最好使用匿名包裝器(譯者注其實(shí)就是我們通常說的自執(zhí)行匿名函數(shù))。

    for(var i = 0; i < 10; i++) {
        (function(e) {
            setTimeout(function() {
                console.log(e);  
            }, 1000);
        })(i);
    }

外部的匿名函數(shù)會(huì)立即執(zhí)行,并把 i 作為它的參數(shù),此時(shí)函數(shù)內(nèi) e 變量就擁有了 i 的一個(gè)拷貝。

當(dāng)傳遞給 setTimeout 的匿名函數(shù)執(zhí)行時(shí),它就擁有了對(duì) e 的引用,而這個(gè)值是不會(huì)被循環(huán)改變的。

有另一個(gè)方法完成同樣的工作,那就是從匿名包裝器中返回一個(gè)函數(shù)。這和上面的代碼效果一樣。

    for(var i = 0; i < 10; i++) {
        setTimeout((function(e) {
            return function() {
                console.log(e);
            }
        })(i), 1000)
    }
上一篇:相等與比較下一篇:typeof 操作符