var, let
- 块级作用域,函数作用域
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
//块作用域
{
var a = 1
let b = 2
console.log(a); //1
console.log(b + ' 块作用域内部'); //2 块作用域内部
}
console.log(a); //1
console.log(b + '块作用域外部'); // b is not defined
//函数作用域
(function() {
var a1 = 1
let b1 = 2
console.log(a1 + ' 函数作用域内部'); //1 函数作用域内部
console.log(b1 + ' 函数作用域内部'); //2 函数作用域内部
})()
console.log(a1 + ' 函数作用域外部'); //a1 is not defined
console.log(b1 + ' 函数作用域外部'); //b1 is not defined
- 变量提升
var存在变量提升,let不存在,即变量只能在声明后使用,否则会报错
console.log(a); //undefined a已声明,但未赋值,打印undefined
console.log(b); //Cannot access 'b' before initialization 初始化前无法访问'b'
var a = 1
let b = 2
- 全局属性
var声明的变量会添加到全局属性上,let不会
var a = 1
let b = 2
console.log(window.a); //1
console.log(window.b); //undefined
- 重复声明
var可以重复声明变量,后声明的会覆盖先声明的,let不可以重复声明变量
var a = 1,
a = 2
let b = 3,
b = 4 //报错
console.log(a); //2
- 暂时性死区
在使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用var声明的变量不存在暂时性死区
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
(function() {
console.log(a); //undefined
console.log(b); //报错
var a = 1
let b = 2
console.log(a); //1
console.log(b); //2
})()
const
const拥有以上let关键字的所有特性,但const更严格
- 初始值设置
let,var声明变量时可以不用设置初始值,const必须设置
var a
let b
const c //报错 必须初始化 "const" 声明
- 指针指向
let,var可以修改指针指向,即可以重新赋值,const 不可以
var a = 1
var a = 2
let b = 1
b = 2
const c = 1
c = 2 //TypeError: Assignment to constant variable. 报错
console.log(a); //2
console.log(b); //2
const定义的对象属性是否可以修改?
const obj = {
name : 'harry',
age : 11
}
obj.name = 'potter'
console.log(obj); //{ name: 'potter', age: 11 }
我们发现name属性被修改了,但是const定义的变量不是不可修改吗?其实不然,const定义的变量只是保存其指针,并非指针指向的内容,内容的改变不影响指针