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