这是我参与8月更文挑战的第二天,活动详情查看:8月更文挑战
变量
JS的变量是松散类型的,也就是说变量可以存储任何类型的数据。JS中有三个关键词可以声明变量,分别是var、let和const。值得一提的是,var是在所有的ECMAScript版本中都可以使用,而let和const必须在ES6及更高版本才可以使用。
var
下面的第一行代码声明了一个a变量,但并没有对a进行初始化赋值,此时a的值为undefined。 第二行代码声明了一个变量b,然后把10这个值赋给了b。
var a;
var b = 10;
需要注意的是:var存在着声明提升的特性。我们知道js执行代码是自上而下的。但是其实这里分了两部,第一步:“预解析”代码,第二步:执行代码,例如:
funciton foo(){
console.log(a);
var a = 10;
}
这个函数是可以正常执行的,并且执行结果打印出来的a为undefined。因为在实际执行过程中,会先声明a,然后再去打印a,最后给a赋值。所以打印出来的是已经声明了但没有赋值的a的值。
let
let和var的作用差不多,但是有着非常重要的区别(面试也常问)。最明显的区别就是:let声明的范围是块级作用域,而var声明的范围是函数作用域。
if(true){
var name = 'juejin';
console.log(name);//这里会打印 juejin
}
congsole.log(name);//这里也会打印 juejin
if(true){
let year = "2021";
console.log(year);//这里会打印出2021
}
console.log(year);//这里会报错ReferenceError:year没有定义
let和var的另一个重要的区别就是,let声明的变量不会在作用域中被提升。
console.log(a);//因为var会提升,所以会打印undefined
var a = 1;
console.log(b);//因为let不会被提升,所以会报错ReferenceError:b没有定义
let b = 2;
实际上,在解析代码的时候,js引擎也会注意出现在块后面的let声明,但是在此之前不能以任何方式来引用未声明的变量,在let声明之前的执行瞬间被称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出ReferenceError的错误。
const
const的行为与let基本上相同,唯一一个重要的区别是const声明变量时必须同时初始化。并且尝试修改const声明的变量会报错。也就是说const一般用于声明一个常量。但是这个限制只适用于const指向的变量的引用,如果const变量引用的是一个对象,那么修改对象的内部属性并不会触发这个限制。
| 变量总结对比 | ||
|---|---|---|
| var | let | const |
| 可以重复声明 | 同一作用域下不可以重复声明 | 不可以重复声明 |
| 函数作用域 | 块级作用域 | 块级作用域 |
| 有声明提升 | 无声明提升 | 无声明提升 |