浅谈 Javascript 中 var,let 和 const 的区别

在初学 Javascript 的时候,笔者学习了变量声明关键字 var,后来在学习 ES6 之后,又学习了两个新的变量声明关键字 let 和 const。那这三者之间有什么区别呢?

一、var
如果使用关键字 var 来声明一个变量,那这个变量就属于当前的函数作用域,也就是局部变量,如果声明是发生在函数外的顶层声明,那么这个变量就是全局变量。
我们可以看一个简单的例子:

var a = 1; //此处声明的变量 a 为全局变量
function foo(){
var a = 2;//此处声明的变量 a 为函数 foo 的局部变量
console.log(a);//2
}
foo();

console.log(a);//1​
 
从这个例子我们可以看到,第一个变量 a 是声明在函数外的,是作用于全局的,所以在调用函数后打印这个变量,它的值是 1。而第二个变量 a 则是局部变量,因为它是申明在函数内的,只在函数内起作用,所以在函数内打印变量,它的值是 2。

那我们再看一个例子:
var a = 1; //此处声明的变量 a 为全局变量
function foo(){
a = 2;//此处声明的变量 a 也是全局变量
console.log(a);//2
}
foo();

console.log(a);//2​
从这个例子,我们可以看到,我们首先申明了一个全局变量 a=1,在函数中我们对 a 进行了赋值,将它赋值为 2 ,在函数内打印结果为 2。这很容易理解。在函数外打印 a,它的结果仍然是 2。这是因为在函数内部我们并没有申明变量,但由于 var 申明的变量存在提升,此时的变量 a 已经提升为全局变量。提升是指无论 var 出现在一个作用域的哪个位置,这个声明都属于当前的整个作用域,在其中到处都可以访问到。注意只有变量声明才会提升,对变量赋值并不会提升。如下例所示:
 
console.log(a);//undefined
var a = 1;​
因为在申明变量之前就使用了 a,此时 a 还未被申明,所有打印出来是 undefined。同理,以下例子也是一样,虽然声明了变量,但是并未赋值,由于赋值不能提升,所以在赋值之前打印 a,仍然是 undefined。
 
var a;
console.log(a);//undefined
a = 1;​


二、let
let 声明的变量,具有如下几个特点:

let 声明的变量具有块作用域的特征。
在同一个块级作用域,不能重复声明变量。
let 声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)。

以下是一个经典的关于 var 和 let 的一个例子:
 
for (var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
},100)
};​
该代码运行后,会在控制台打印出 10 个 10。若修改为:

for (let i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
},100)
};​
则该代码运行后,由于 let 块级作用域的特征,就会在控制台打印出 0-9。

三、const
const 声明方式,除了具有 let 的上述特点外,其还具备一个特点,即 const 定义的变量,一旦定义后,就不能修改,即 const 声明的变量为常量。
举个例子:
const a = 1;
console.log(a);//1
a = 2;
console.log(a);//Uncaught TypeError: Assignment to constant variable.​
因为 a 被 const 申明为常量,不能再对其进行赋值,所以报错。但是,并不是说 const 声明的变量其内部内容不可变,比如:
 
 
const person = {name:"KK",age:18};
console.log(person.b);//18
person.b = "25";
console.log(person.b);//25
所以准确的说,是 const 声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。因为案例中对象是引用类型的,person 中保存的仅是对象的指针,这就意味着,const 仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的。也就是说 const 定义的引用类型只要指针不发生改变,其他的不论如何改变都是允许的。

四、总结

var 声明的变量属于函数作用域,let 和 const 声明的变量属于块级作用域;
var 存在变量提升现象,而 let 和 const 没有此类现象;
var 变量可以重复声明,而在同一个块级作用域,let 变量不能重新声明,const 变量不能被修改。

五、参考资料
参考文章:https://blog.csdn.net/unionz/article/details/80032048


★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论