JS塊級作用域與函數作用域–ES6 let


原文地址:http://blog.csdn.net/qq_22755565/article/details/62422048

ES5沒有塊級作用域

ES5中沒有塊級作用域,只用函數作用域,來看下面一段代碼

for (i = 0; i < 1; i++) { var forVar = 'forVar'; } console.log(forVar); //'forVar'在for循環中定義的變量forVar可以在for代碼塊外訪問 function fn() { var fnVar = 'fnVar'; } console.log(fnVar);//fnVar is not defined,在fn()函數內部定義的變量fnVar不可以在fn()函數外訪問
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

沒有塊級作用域導致的問題

循環變量泄漏為全局變量

來看使用閉包經常會遇到的一個現象

function test() { var arr = new Array(); for (var i = 0; i < 6; i++) { arr[i] = function() { return i;//i只用來控制循環,循環結束后泄漏成了test函數的變量 } } return arr; } var arrObj = new test(); console.log(arrObj[0]());//6arrObj[0]訪問的是test函數作用域下的變量i,test中i只用來控制循環,循環結束后泄漏成了test函數的變量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在上面的例子中由於沒有塊級作用域的概念變量i在循環后泄漏為test()函數中的變量,在返回的函數數組中的每一個函數引用的都是test()函數中的變量i

ES5模仿塊級作用域

針對上面出現的情況,通常會通過創建匿名函數的方式實現想要的結果

function test() { var arr = new Array(); for (var i = 0; i < 6; i++) { arr[i] = function(j) { return function (){ return j; } }(i) } return arr; } var arrObj = new test(); console.log(arrObj[0]());//0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在上面的代碼中,使用了一個立即執行的匿名函數,在每一次循環中匿名函數中的變量j在函數執行結束后都會被銷毀

ES6塊級作用域

ES6新增了let命令用來進行變量聲明,使用let命令聲明的變量只在let命令所在代碼塊內有效

{
    var kuaiVar = 'kuaiVar'; let kuaiLet = 'kuaiLet'; } console.log(kuaiVar, kuaiLet); //kuaiVar,kuaiLet is not defined for (i = 0; i < 1; i++) { var forVar = 'forVar'; let forLet = 'forLet'; } console.log(forVar, forLet); //forVar,forLet is not defined function fn() { var fnVar = 'fnVar'; let fnLet = 'fnLet'; } console.log(fnVar, fnLet);//fnVar is not defined,fnLet is not defined (function() { for (i = 0; i < 1; i++) { var fnForVar = 'fnForVar'; } })();//使用匿名函數模仿塊級作用域 console.log(fnForVar); //fnForVar is not defined

這時我們只需用let替換原來的var就可以避免循環變量泄漏為全局變量的問題

 function test() { var arr = new Array(); for (let i = 0; i < 6; i++) { arr[i] = function() { return i; //i只在for循環內有效 } } return arr; } var arrObj = new test(); console.log(arrObj[0]());//0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM