- 2.1 var 声明的变量没有
块级作用域, const 和 let 有块级作用域
var blackVar = 'a';
let blackLet = 'b';
if(true) {
var blackVar = 'c';
let blackLet = 'd';
};
console.log('blackVar', blackVar); // c
console.log('blackLet', blackLet); // b
- 典型的面试
// 其中 var 为什么都是 5 的原因:因为 var 没有块级作用,所以去 i 的最后一个值 5(定时器是宏任务所以会在for 循环结束之后在执行)
for(var i =0; i < 5; i++) {
setTimeout(() => {
console.log('var', i); // 都是 5
})
};
// let 有块级作用域,let 的值是不会相互影响的
for(let i = 0; i < 5; i++) {
setTimeout(() => {
console.log('let', i); // 0,1,2,3,4,
});
};
-
var为什么都是 5:因为 var 没有块级作用,所以去 i 的最后一个值 5(定时器是宏任务所以会在for 循环结束之后在执行) -
let有块级作用域,let 的值是不会相互影响的 -
2.2
const是常量 赋值之后 不能修改存储地址,let和var赋值之后是可以被修改的
const constant = '基本数据类型是不可以修改里面的值的';
const constantObj = {
name: '引用数据类型的属性时可以被修改的,因为不改变引用地址',
};
// constant = '我不能被修改'; // 会报错:Assignment to constant variable
constantObj.name = '我可以被修改'; // const 声明的引用数据类型是可以添加修改属性和方法的,因为不改变引用类型的存储地址
console.log(constantObj, 'constantObj');
-
const 声明的引用数据类型是可以添加修改属性和方法的,因为不改变引用类型的存储地址
-
2.3
let和const在同一个作用域下是不能被重复声明的,var可以重复声明
let repeat = '我先声明';
// let repeat = '我后声明'; // 报错:'repeat' has already been declared
var repeatVar = '我用 var 先声明';
var repeatVar = '我用 var 后声明';
console.log(repeatVar, 'repeatVar'); // var 是可以重复声明但是声明的值会被覆盖
-
var 是可以重复声明但是声明的值会被覆盖
-
2.4
变量提升 -
JavaScript 引擎在解析代码的时候存在
预解析和执行两个阶段 -
引擎会对
var声明的变量 和函数声明提升到当前作用域的最前面 先进行创建和初始化 -
var声明的变量会先创建,并初始化为undefined -
函数声明会创建并赋予函数体,但是不会被调用
console.log(stateVar, 'stateVar'); // undefined
stateFn(); // 我是 函数声明
var stateVar = '我是var声明的变量';
function stateFn() {
console.log('我是 函数声明');
};
- 关于 let 和const 是否有
变量提升呢? - 官方给出的解释是:
暂时死区:let 和const 不会进行变量提升,在声明之前不能使用,形成暂存死区 - 但是我觉得是有的,原因如下:
let promoteLet = 'let 是否有变量提升';
if(true) {
console.log('promoteLet', promoteLet); // 报错:Cannot access 'promoteLet' before initialization
// 我的理解是 let 声明的过程是 创建 -> 初始化 -> 赋值 三个阶段
let promoteLet = 'let 没有变量提升';
};
- 我在块级作用域中访问
promoteLet的值,如果 let 没有变量提升的话,他通过作用域链应该获取全局声明的值,但是他却报错:Cannot access 'promoteLet' before initialization,我的理解是 let 声明的过程是 创建 -> 初始化 -> 赋值 三个阶段 let 声明的变量是有被提升到作用域最上面,只是没有被初始化,所有会报错
最后,感谢这篇博文,本文中的部分内容参考自这篇博文:我用了两个月的时间才理解 let