共计 1447 个字符,预计需要花费 4 分钟才能阅读完成。
ES 6 新增的块级作用域 let
在 2015 年之前,JavaScript 是没有块级作用域的,之后在 ES6 版本新增了块级作用域,为了更好的理解 ES6 这一新特性,我们先提出这几个问题:
1. 什么是块级作用域?
2. 为什么要添加块级作用域?
3. 怎么使用块级作用域?
什么是块级作用域?
块级作用域,就是指在只能在语句块这个范围中起作用,超出这个范围则无效,其中语句块,是指将多个语句放在一对大括号 {} 里面,通常用于流程控制,比如 if,for,while
等等。
示例
while (x < 10) {if(x>5){x++;}
}
这里 {if(x>5){x++;}}
是一个语句块,{x++;}
也是一个语句块,巧记:一对大括号就是一个语句块,就代表一个作用域。
为什么要添加块级作用域?
ES6 之前,变量只有全局作用域(也称全局变量)和函数作用域(局部变量),所以会导致以下不合理的情况:
1. 函数的局部变量会覆盖同名的全局变量。
示例
var a = 0
(function() {console.log('函数内部调用全局的 a:', a) // 输出:函数内部调用全局的 a:0
})()
console.log('全局变量 a:', a) // 输出; 全局变量 a:0
var a = 0
;(function() {console.log('a=', a) // 输出:a= undefined,按理说应该输出 a =0
if (false) {
var a = 1
console.log(a)
}
})()
原因
变量提升导致内层的 a 变量覆盖了外层的 a 变量。
这就导致了如果你要在函数内部调用全局变量,那么函数内声明的局部变量就一定不能和全局变量同名。
2. 函数内部中,只要声明了变量,之后在函数结束前,都可以使用。
示例
(function() {console.log(a) // 输出:undefined
if (true) {for (var a = 0; a < 10; a++) {
var b = 0
console.log(a) // 输出:0~9
}
}
console.log('if 之外 a:', a) // 输出:if 之外 a:10
console.log('if 之外 b:', b) // 输出:if 之外 b:0
})()
原因
在 for 循环中声明的 a,b 变量,在函数结束前并不会被销毁。
这样就导致了一些不必要的内存消耗。
为了避免这两个不合理的问题,块级作用域就出现了。
怎么使用块级作用域?
使用变量命令 let
。
示例
(function() {if (true) {for (let a = 0; a < 10; a++) {console.log(a) // 输出:0~9
}
}
console.log('if 之外 a:', a) // 报错:ReferenceError: a is not defined
})()
对于 let
命令的变量:
- 作用域:变量所在的语句块,即一对大括号{};
- 不存在变量提升,而是“暂时性死区”,也就是说从块级作用域开始到声明该变量,这段时间里是不能访问该变量的;
- 同一语句块中,不能被同一变量名不能重复声明。
- 经典案例:
let
命令代替闭包功能
闭包实现:
var arr = [];
for(var i = 0; i < 2; i++){arr[i] = (function(i){return function(){console.log(i);
};
}(i));
};
arr[1]();
let 实现:
'use strict';
var arr = [];
for(let i = 0; i < 2; i++){arr[i] = function(){console.log(i);
};
};
arr[1]();
参考文章:
- ES6 中啥是块级作用域?运用在哪些地方?
- 变量作用域
正文完
发表至: javascript
2019-07-17