一、什么是提升?
JS引擎会在JS代码执行前先进行预编译,预编译期间会将变量声明与函数声明提升至其对应作用域的最顶端。
二、变量提升
ES6之前我们一般使用var来声明变量,变量提升简单来说就是把我们所写的类似于var str = 'test';这样的代码,声明提升到它所在作用域的顶端去执行,到我们代码所在的位置来赋值。
function test() {
console.log(str); // 会输出 undefined
var str = 'test';
}
test();
相当于以下代码:
function test() {
var str;
console.log(str);
a = 'test';
}
test();
下面看一道经典的题目:
// 代码段1--------------------------
var myvar = "变量值";
console.log(myvar); // 输出 变量值
// 代码段2--------------------------
var myvar = "变量值";
(function () {
console.log(myvar); // 输出 变量值
})();
// 代码段3----------------------------
var myvar = "变量值";
(function () {
console.log(myvar); // 输出 undefined
var myvar = "内部变量值";
})();
ES6引入了新的定义变量关键字:let、const。用let或者const定义的变量不存在变量提升;同时也增加了新的作用域:块级作用域。
三、作用域
在早期的ES5中,JS的作用域分为两种,全局作用域和局部作用域。之后在ES6中添加了块级作用域,主要通过命令let和const来实现。
ES5只有全局作用域和函数作用域,没有块级作用域,会带来以下问题:
1.变量提升导致内层变量可能会覆盖外层变量。
2.用来计数的循环变量泄露为全局变量等等。
日常编写代码中,尽量用let以及const。