var关键字
作用域
var
声明变量的作用域为该语句所在的函数内。
var a = 111; // 在函数外部声明作用域为全局
(function () {
var b = 222; // 变量b的作用域仅在函数内部
console.log(b); // 输出 222
})()
console.log(a); // 输出 111
console.log(b); // 变量b没有被定义
变量提升
var
声明的变量会发生“变量提升”现象,即变量可以在声明之前使用,且值为undefined
。
// var 存在变量提升
console.log(a); // 输出 undefined
var a = 111;
// let 不存在变量提示
console.log(a); // 报错 ReferenceError
let b = 222;
重复声明
var
声明的变量允许重复声明,后者会替代前者。
var a = 111; // 变量b的作用域仅在函数内部
console.log(a); // 输出 111
var a = "hello"
console.log(a); // 输出 hello
let关键字
作用域
let
声明变量的作用域为该语句所在的代码块内。
let a = 111; // 在函数外部声明作用域为全局
{
let b = 222; // 变量b的作用域仅在代码块内部
console.log(b); // 输出 222
}
console.log(a); // 输出 111
console.log(b); // 报错 ReferenceError
变量提升
let
声明的变量不存在“变量提升”现象,它所声明的变量一定要在声明后使用,否则报错。
// var 存在变量提升
console.log(a); // 输出 undefined
var a = 111;
// let 不存在变量提示
console.log(a); // 报错 ReferenceError
let b = 222;
重复声明
let
声明的变量不允许重复声明,重复声明会报错。
let a = 111; // 变量b的作用域仅在函数内部
console.log(a); // 输出 111
let a = "hello"
console.log(a); // 报错 SyntaxError
暂时性死区
var value = 111;
if(true){
value='abc'; // 报错 ReferenceError
let value;
}
上述代码中,存在全局变量value
,但是块级作用域内let又声明了一个局部变量value
,导致后者绑定这个块级作用域,所以在let
声明变量前,对value
赋值会报错。
总结var和let的区别
-
var
声明的变量作用域为该语句所在的函数内。let
声明的变量作用域为该语句所在的代码块内。 -
var
存在变量提升现象,let
不存在变量提示现象。 -
var
允许在相同作用域内,重复声明同一个变量。let
不允许在相同作用域内,重复声明同一个变量。
const关键字
const
意为constance
即常量、不变量的意思。其声明一个只读的变量,这意味着:这个变量一旦声明就必须初始化,否则就会报错。其作用域、暂时性死区等特性和let
一致。
const注意事项
- 声明必须初始化。
- 对于简单类型(数值 number、字符串 string 、布尔值 boolean、symbol)等同于常量。
- 对于复杂类型(对象 object,数组 array,函数 function)只保证指向复杂类型内存地址的引用(指针)不变,至于指针指向的数据变不变就无法控制了。
const a = 111;
a = 222; // 报错 TypeError 对于简单类型,const类型变量的值不可改变
const b // 报错 SyntaxError const类型变量必须初始化
const obj = {
name: 'pray',
age: 18
}
obj.age = 20; //对于复杂类型,仅仅是引用不可改变,其内容是可以改变的