块级作用域
let、const
ES6中新增了let以及const声明变量,两种方式所声明变量只会在当前代码块内有效。
{
let num=10;
console.log(num); // 10
}
console.log(num); // num 未定义
暂时性死区:
即只要块级作用域中存在let或者const声明的变量,它所声明的变量就“绑定”(binding)这个区域,不受外部影响。并且在let所在代码块中,在let声明改变量之前,该变量都是不可使用的,在语法上称为暂时性死区。
var num = 123;
{
num = 456;
let num; //num is not defined
//由于该代码块内存在let声明的num变量,
//因此与此区域绑定,不受外部影响,由于未声明就使用,所以num is not defined
}
块级作用域:
由于let以及const暂时性死区原因,为javascript新增了块级作用域。
即在当前代码块声明的let、const变量只会作用与当前代码块内
即:
function foo() {
let n = 5;
if (true) {
//当前n只会作用于当前{}内不会影响外层
let n = 10;
console.log(n) //10
}
console.log(n) //5
}
foo()
块级作用域与函数声明:
ES5规定,函数只能在顶层作用域和函数作用域之中声明,无法在块级作用域声明
即:
if (true) {
function foo() {
}
}
在ES5中上述声明是禁止的,但是浏览器为了兼容以前旧代码,还是支持在块级作用域声明函数。
在ES6规定允许在块级作用域声明函数,作用相当于let不可在块级作用域外使用;
function foo() {
console.log("out")
}
(function () {0
if (false) {
function foo() {
console.log("in")
}
}
foo();
}())
在ES5 foo()执行结果为 “in",ES5会将if内部声明的函数提升到函数头部
(function () {
function foo() {
console.log("in")
}
if (false) {
}
foo();//in
}())
在ES6中,理论上{代码块}声明的函数不会作用于外层所以应该为"out",实际会报错foo is not function 。
由于改变块级作用域的函数处理规则,会影响旧代码,因此允许浏览器可以不遵守该处理规则(不可在块级作用域外使用)。具体为:
1.允许在块级作用域声明函数
2.函数声明类似var会存在变量提升,会提升到全局作用域或者函数作用域头部
3.同时函数声明会提升到所在块级作用域头部`;
即ES6中实际为:
function foo() {
console.log("out")
}
(function () {
var foo=undefined;
if (false) {
function foo() {
console.log("in")
}
}
foo();//这个时候foo为undefined
}())