什么是变量提升?
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
一)var 声明变量存在变量提升,let 和 const 不存在变量提升
console.log(a); // undefined ===> a 已声明还没赋值,默认得到 undefined 值
var a = 100;
console.log(b); // 报错:b is not defined ===> 找不到 b 这个变量
let b = 10;
console.log(c); // 报错:c is not defined ===> 找不到 c 这个变量
const c = 10;
再来看这段代码
function fn() {
//var a
if (true) {console.log(a + 'now')
}
else {
var a = 1
console.log(2)
}
}
fn() // a -> undefined
我们发现不执行的代码也会影响会执行的代码,因为 var a 会提升到 if 语句的前面
undefined 可以翻译为不明确,not defined 可以翻译为未定义
在 Java 中变量的分为全局变量(成员变量)或者局部变量,在方法体中定义的变量都是局部变量,否则是全局变量(即在方法体外,在类中定义的变量)
在 JavaScript 中,在方法体外外用 var 定义的变量其它方法可以共享,在方法中用 var 定义的变量只有该方法内生效。
二)let、const 都是块级局部变量
顾名思义,就是只在当前代码块起作用
{let a = 1}
console.log(a) // undefined
const 的特性和 let 完全一样,不同的只是
1)声明时候必须赋值
const a
编译器报错
控制台报错
SyntaxError: Missing initializer in const declaration
2)只能进行一次赋值,即声明后不能再修改
const a=1
a=2
编译器报错
控制台报错
TypeError: Assignment to constant variable.
3)如果声明的是复合类型数据,可以修改其属性
三)同一作用域下 let 和 const 不能声明同名变量,而 var 可以
const a =2
const a=1
SyntaxError: Identifier 'b' has already been declared
面试题
简单的 Demo
for (let i = 0; i < 5; i++) {console.log(i)
}
上面的代码我们知道打印结果是 0, 1, 2, 3, 4,但是你们有没有想过这个变量 i 的作用域到底是什么呢?
有人说在这个 for 循环里呀,但是我这里想说的是这个 i 作用域是在括号 () 里。正常的代码是这样的:
1. 首先这个变量_i 的作用域是在 () 里才有效的,循环体里是不能访问到_i 的
2. 每次循环的时候创建一个 i 变量,将括号里的_i 赋值到变量 i 上
3. 最后 i ++ 后再将变量 i 的值赋值回_i 上
当然这个过程是很复杂的,可以用下面代码理解,但是 JS 的实现机制是很复杂的,这里想要说明的 let i 的作用域有时候并不是我们所理解的那样的。
for (let _i = 0; i < 5; i++) {
let i = _i
console.log(i)
// i++ 先做
_i = i
}
个人网站