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
也沒有污染到外部的全局做用域