var
新创建的变量的默认值都是 undefined。
var testThis
console.log(testThis)
变量赋值:
testThis = 'helloWord'
在方法内部定义的var 变量,方法内部都可以访问到这个变量。
例如for循环中
for(var i =0;i<length;i++){
var test = i
}
console.log(i)
console.log(test)
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i) //输出三个3
}, 1000);
}
循环本身及三次 timeout 回调均共享唯一的变量 i 。
当循环结束执行时,i 的值为3。所以第一个 timeout 执行时,调用的 i 也为 3 。
let
let 是块作用域,即其在整个大括号 {} 之内可见。
在变量声明之前就访问变量的话,提示 ReferenceError,而 var 使用默认值 undefined。
for(leti =0;i<length;i++){
console.log(test) //ReferenceError
let test = i
}
console.log(i) //ReferenceError
console.log(test)
不允许重复声明
// 报错
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
function func(arg) {
let arg; // 报错
}
function func(arg) {
{
let arg; // 不报错
}
}
const
作用域与let命令相同:只在声明所在的块级作用域内有效,不同的是 const 变量一旦被赋值,就不能再改变了
声明一个只读的常量。一旦声明,常量的值就不能改变。
声明的变量不得改变值,一旦声明变量,就必须立即初始化,不能留到以后赋值。
声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const num = 1000;
num = 2000; // 会报错 ,因为在同一作用域,num的值已经固定,不可改变。
const声明创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。
const num = {a:1000};
num.a = 2000 ; //这个不会报错 ,因为其属性值可以被改变,可以改变对象内容,但不能改变在内存中的表示和位置。
区别
- 作用域:let和const声明形成块作用域
- 同一作用域下let和const不能声明同名变量,而var可以
- var声明的变量会挂载在window上,而let和const声明的变量不会
- var声明变量存在变量提升,let和const不存在变量提升
- 暂存死区(当前作用域顶部到该变量声明位置中间的部分,都是该let变量的死区,在死区中,禁止访问该变量。由此,let声明的变量存在变量提升, 但是由于死区我们无法在声明前访问这个变量。)
var a = 100;
if(1){
a = 10;
//在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a,
// 而这时,还未到声明时候,所以控制台Error:a is not defined
let a = 1;
}
使用
大多数情况下都使用 const,除非知道变量的值还会被改变。
如果这个变量的值的确需要改变,例如 for 循环,就用 let。
少用var