let、const和var的区别
Contents
变量提升
变量提升:
- 所有的声明都会提升到作用域的最顶上去。
- 函数声明的优先级高于变量声明的优先级,并且函数声明和函数定义的部分一起被提升。
一个变量有三个操作,声明(提到作用域顶部),初始化(赋默认值),赋值(继续赋值)。
let
const
和var
三者都会存在变量提升
-
let
只是创建过程提升,初始化过程并没有提升,所以会产生暂时性死区。 -
var
的创建和初始化过程都提升了,所以在赋值前访问会得到undefined
-
function
的创建、初始化、赋值都被提升了
console.log(data1); //undefined
var data1 = 'var';
console.log(data2); //Uncaught ReferenceError: Cannot access 'data2' before initialization
let data2 = 'let';
console.log(data3); //Uncaught ReferenceError: Cannot access 'data3' before initialization
const data3 = 'const';
声明
var
声明变量可以重复声明,而let
、const
不可以重复声明。const
声明之后必须赋值,否则会报错。const
定义不可变的量,改变了就会报错。但是const
仅保证指针不发生改变,修改对象的属性不会改变对象的指针,所以是被允许的
作用域
- 比如模块或者一个方法中声明的
var a=1
,如果声明在模块中,则会默认挂载到window
上;如果声明在方法中,则在方法内部任何地方都可以访问;如果声明在代码块里,则会提升到上一级作用域; - 而
let
、const
仅作用于块级作用域,仅在该块级内起作用。
if(true){
var color = "red"
}
console.log(color) //'red'
if(true){
let color = 'red'
}
console.log(color) //ReferenceError
在es5环境下实现const
function _const(key, value) {
const desc = {
value,
writable: false
}
Object.defineProperty(window, key, desc)
}
_const('obj', {a: 1}) //定义obj
obj.b = 2 //可以正常给obj的属性赋值
obj = {} //抛出错误,提示对象read-only