本篇文章帶給大家的內容是關於js中區塊層級作用域以及函數作用域之間有什麼差別? (程式碼解析),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
ES5只有全域作用域沒和函數作用域,沒有區塊級作用域,這帶來很多不合理的場景。
第一種場景,內層變數可能覆寫外層變數:
var tmp = new Date(); function f(){ console.log(tmp); if(false){ var tmp = "hello"; } } f(); // undefined
上面程式碼中,函數f
執行後,輸出結果為undefined
,原因在於變數提升,導致內層的tmp
變數覆蓋了外層的tmp
變數。
第二種場景,用來技術的循環變數洩漏為全域變數:
var s = "hello"; for(var i=0;i<s.length;i++){ console.log(s[i]); } console.log(i); // 5
上面程式碼中,變數i
只用來控制循環,但是循環結束後,它並沒有消失,洩漏成了全域變數。
let
實際上為JavaScript新增了區塊級作用域
function f1(){ let n = 5; if(true){ let n = 10; } console.log(n); // 5 }
上面的函數有2個程式碼塊,都宣告了變數n
,運行後輸出5。這表示外層程式碼區塊不受內層程式碼區塊的影響。如果使用var
定義變數n
,最後輸出的值就是10。
外層作用域無法讀取內層作用域的變數:
{ {let insane = "hello"} console.log(insance); // 报错 }
內層作用域可以定義外層作用域的同名變數:
{ let a = "hello"; {let a = "hello"} }
區塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函數表達式(IIFE)不再必要了:
// IIFE写法 (function(){ var tmp = ...; ... }()); // 块级作用域写法 { let tmp = ...; ... }
ES6以前變數的作用域是函數範圍,有時在函數內局部需要一些臨時變量,因為沒有區塊級作用域,所以就會將局部程式碼封裝到IIEF中,這樣達到了想要的效果又不引入多餘的臨時變數。而塊作用域引入後,IIEF當然就不必要了!
function f(){ ... swap(var_a,var_b); (function swap(a,b){ var tmp; tmp = a; a = b; b=tmp; })(var_a,var_b); }
如上面的程式碼,tmp被封裝在IIFE中,就不會污染上層函數;而有區塊級作用域,就不用封裝成IIEF,直接放到一個區塊級中就好。
function f(){ let a,b; ... { let tmp; tmp = a; a = b; b=tmp; } }
更簡單的說法是,立即執行匿名函數的目的是建立一個區塊級作用域,那麼現在已經有了真正的區塊級作用域,所以立即執行匿名函數就不需要了。
相關推薦:
#以上是js中區塊級作用域以及函數作用域之間有什麼區別? (程式碼解析)的詳細內容。更多資訊請關注PHP中文網其他相關文章!