JS块级作用域与函数作用域–ES6 let

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_22755565/article/details/62422048

JS块级作用域与函数作用域–ES6 let

今天在学习ES6时看到新增了块级作用域的概念,于是回顾一下ES5中的函数作用域加深印象


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()函数外访问

没有块级作用域导致的问题

循环变量泄漏为全局变量

来看使用闭包经常会遇到的一个现象

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函数的变量

在上面的例子中由于没有块级作用域的概念变量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

在上面的代码中,使用了一个立即执行的匿名函数,在每一次循环中匿名函数中的变量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循环内有效,每次循环都会创建新的变量i
        }
    }
    return arr;
}
var arrObj = new test();
console.log(arrObj[0]());//0

**注意:**本文参考了阮一峰的《ECMAScript 6 入门》还参考了《javaScript高级程序设计》,文章内容都是自己的理解,有不对的地方还请各位指出。


猜你喜欢

转载自blog.csdn.net/qq_22755565/article/details/62422048