首先我们了解下何为关键字:在js里,关键字是有特殊用途,用来表示控制语句的开始和结束,或者执行特定的操作。今天我们来聊聊var、let和const这三个关键字。这三个关键字都可以声明变量,那它们的区别在哪?请往下看
var关键字
var声明作用域
--- 使用var操作符定义的变量会成为包含它的函数的局部变量。比如,使用var在一个函数内部定义一个变量,就意味着该变量会在函数退出时销毁:
function test() {
var message = "hi";//局部变量
}
test();
console.log(message);//出错
--- 这里报错就是因为var在test函数内部定义了一个message变量并且给它赋值为hi,但是当test函数调用message变量之后随机被销毁,因而无法输出,随即报错。 不妨看看如下代码:
function test() {
message = "hi";//全局变量
}
test();
console.log(message);//"hi"
--- 这里将var操作符去掉之后,message随即变成全局变量,调用test函数之后,就可以在函数外部访问并输出。
由此我们得到var声明的变量是函数作用域;
var声明提升
--- 来看以下代码:
function foo() {
console.log(age);
var age=26;
}
foo();// undefined
--- 没有报错,是因为var age 被提升至函数作用域顶部,即等价于如下代码:
function foo() {
var age;
console.log(age);
age=26;
}
foo();// undefined
--- 这就是提升(host),就是var声明变量会被拉到函数作用域的顶部。
由此我们得到var声明变量会提前到文件最开始的地方,但是初始化还是在语句位置。
let声明
let与var的区别在于let声明的是块作用域,而var声明的范围是函数作用域。
if(true){
var name = 'li'
console.log(name);//li
}
console.log(name);//li
if(true){
let age =26;
console.log(age);//26
}
console.log(age);//age 未定义
--- 通过对比这两段代码就能很清晰的看出var和let之间的区别,name可以在if块外部被引用,但是age却不能在if块外部被引用,就是因为age的作用域仅限于该块内部,无法被调用。
let也不允许同一个块作用域中出现冗杂声明,这也是我们在日常编程中需要注意的问题。
var name;
var name;
let age;
let age;//age has already been declared
暂时性死区
let与var的另一个重要区别是let声明的变量不会在作用域中被提升
//name 会被提升
console.log(name)//undefined
var name = 'li';
//age 不会被提升
console.log(age)//age未定义
let age =26;
--- 只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
全局声明
使用let在全局作用域中声明的变量不会成为window对象的属性,而var声明的对象则会
var name = 'li';
console.log(window.name);//li
let age = 26;
console.log(window.age);//undefined
for循环中的let声明
--- 我们先来看看两段代码
for(var i = 0; i < 5; ++i){
//循环逻辑
}
console.log(i)//5
for(let i = 0; i < 5; ++i){
//循环逻辑
}
console.log(i);//i没有定义
--- 使用var的时候,for循环定义的迭代变量会渗透到循环体外部,但使用let之后,这个问题就消失了,因为作用域仅仅局限于for循环块内部。 我们再来看下有意思的事情
for(var i = 0; i < 5; ++i){
setTimeout(()=>console.log(i),0)
}//5,5,5,5,5
for(let i = 0; i < 5; ++i){
setTimeout(()=>console.log(i),0)
}//0,1,2,3,4
--- 第一段代码之所以会出现的情况,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5,在之后执行的逻辑中,所有的i都是同一个变量,因此都输出5。而第二段代码中,js在执行过程中为每个迭代循环声明一个新的变量,因此循环过程中会执行每个迭代变量的值。
const声明
--- const与let大体相同,唯一一个重要区别是它声明变量时必须同时初始化变量,且修改const声明的变量会报错。
const age = 26;
age = 36// TypeError
总结
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。同一个变量只能使用一种方式声明,不然会报错
--- 以上就是我对js三个关键字的一点拙见,未完待续........