之前一直觉得这个自己可以回答上来,…呵呵呵,原来这么一个小小的知识点我都是模棱两可的,害,学习这个东西吧,模棱两可真的是最可怕的,这也是我最容易犯的一个错误,总觉得自己大概会,其实遇到具体的问题就开始ran了hhh。所以,还是不能忽略基础知识的,没有一块块小砖,怎么盖成大房子呢,对吧。
所以我遇到小小的知识点,也要养成写到博客上的好习惯,因为我发现写博客真的很有用,因为写到自己的博客上面,是用自己的理解和记忆的方式来进行学习的,而且学习过很容易就会忘掉,记到自己的博客上面,查起来真的也会方便很多很多。
关于var,let,const这个问题,我觉得真的很有必要梳理一下,平时写代码要用,面试也经常问,然后刚好今天看书看了一下这个,就总结一下它们的区别⑧。
首先,let和const是ES6新增的声明变量的方式,相比较于var,当然推荐使用它们啦。
列举一下它们的区别:
- 作用域:
区别:var声明的范围是函数作用域,let和const声明的范围是块作用域。
var:使用var定义的变量会成为包含它的函数的局部变量。
举个栗子:
function test(){
var a = 1;
}
test();
console.log(a)//ReferenceError: a is not defined
因此,使用var在函数内部声明的变量,函数执行后就会被销毁,就不可以再使用这个变量了。
let:使用let声明的变量,它的作用域仅仅在块内部。
if(true){
let a = 1;
console.log(a)//1
}
console.log(a)//ReferenceError: a is not defined
因此这一点除了作用域以外,和var是一样的,都仅仅可以在自己的作用域内访问到这个变量,在作用域外访问就会出现错误。
const:const和let声明的作用域范围都是块。在作用域方面和let是一样的。
- 全局声明:
使用var在全局作用域中声明的变量会成为window对象的属性,let和const不会。但是使用let和const声明的变量作用域还是在全局的,因此后面全局不可以再重复声明同一个变量了。(var声明在同一个作用域内都可以重复声明,let和const不可以在同一个作用域里面重复声明)
var a = 1;
console.log(window.a)//1
let b = 1;
console.log(window.b)//undefined
const c = 3;
console.log(window.c)//undefined
- 声明提升
使用var声明的变量会进行预编译,发生变量提升,就像下面这样:
console.log(a)//不会报错,结果是:undefined
var a = 1;
用var声明的变量a会被提升到代码的顶部,上面这段代码就相当于下面这样:
var a;
console.log(a)
a = 1;
但是使用let和const声明的变量就不会在作用域中被提升。变量会被放到暂时性死区,在声明这个变量之前都不能对这个变量进行引用。
因此要是把前面代码里面的var换成let或者const,就会发生错误。
for循环
像下面这个代码:
for(var i = 0;i < 10;i++){
setTimeout(() => console.log(i),0)
}//输出了10个10
换成let之后,
for(let i = 0;i < 10;i++){
setTimeout(() => console.log(i),0)
}//输出:0 1 2 3 4 5 6 7 8 9
因为使用var声明时,在退出循环的时候,变量保存的是导致循环退出的值,在之后执行超时逻辑时,所有的i都是同一个变量。但是使用let声明时,每次循环都会声明一个新的变量,输出的就是每个变量的值。
注意:这种情况下的for循环是不可以使用const声明变量的,会发生类型错误。原因:const在其他方面和let都是一样的,但是const有一个不同的地方是----声明变量时必须同时初始化变量,而且变量不可以再进行修改了。
const a = 1;//这行换成let、var的话,结果就会是:2
a = 2;
console.log(a)//TypeError: Assignment to constant variable.
虽然使用const声明的变量不可以再进行修改了,但是有一个特殊的情况:
如果const变量引用的是一个对象,那么可以修改这个对象内部的属性,因为const声明的限制只适用于它指向的变量的引用。
const obj = {
a:1,
b:2
}
obj.a = 3;
obj.c = 9;
console.log(obj.a,obj.b)//3,2
在使用的时候,优先的顺序:const>let>var