從一個小題目談談js函數閉包

先來看一個問題

題目

var str1 = str2 = "web";
(function () {
var str1 = str2 = "前端";
})();
console.log(str2);

固然這裏輸出的是結果是: 前端javascript

若是如今將console.log(str2)變成consloe.log(str1),那麼輸出的結果就會變成 web前端

解答

其實這題並非很難,第一句 var str1 = str2 = "web"; 實際上是定義了兩個全局的變量,在利用function的閉包內用 var 從新定義了 str1 而沒有從新定義 str2 java

咱們知道在默認狀況下 若是不用 var 定義的變量都會變成全局變量,因此此時在function閉包內的str2就是引用了全局變量,因此賦值操做固然也就能賦予全局變量 str2 因此輸出 str2 結果是 "前端"web

str1 用了 var 定義,就是在function閉包內的變量,閉包外天然不能夠改變,因此輸出的結果是 "web"閉包

腦洞大開

其實每一次看到這種形式的代碼函數

(function(){
})()

都以爲很是的新鮮,以爲這裏有不少東西能夠專研,因此在這裏也總結一下這種形式的閉包。code

解釋前先看看

首先這種形式的閉包是人爲的加上去,並非說能夠有什麼神奇的 duangduang 的特效,而是能夠避免不少原本是局部變量能夠搞定的比較 low 的變量去污染全局的變量 ip

其次在js中,是 沒有塊做用域 這種說法
首先咱們回到C++,若是有一段代碼是這樣作用域

int number1=10;
    if(true){
      int number1 = 5;
    }
    cout<<number1;

這裏的結果仍是 10 io

而在js代碼之中

var str1= "web";
    if(true){
        var str1="前端";
    };
    console.log(str1);

這裏的結果就是 前端

由於 if{} 沒有塊做用域,因此內部的str1直接就重定義了外部全局的str1,因此輸出的結果就只是"前端"了,並且這也污染了全局變量(那個等於"web"的str1已經不見了蹤跡)

而大 js 只有 函數做用域

因此咱們要利用函數閉包

利用函數閉包能有效的封裝局部的變量,而不污染全局做用域

str1 = "web";
    (function () {
         var str1 = "前端";

         //str1剩下的功能
    )();
    console.log(str1);

此時輸出的仍是 web

因此咱們利用了一個匿名函數 function(){} 而且讓他本身調用本身執行函數內部的操做 而且 str1 也沒有污染到外部的全局做用域

相關文章
相關標籤/搜索