1.首先什么是变量提升
- 函数及变量的声明都将被提升到函数的最顶部。
注释:仅仅是被声明,而不是被赋值,函数的优先级会高于变量
还有一个有趣现象是,如果注释掉console.log(a) //undefined console.log(b) //报错 Cannot access 'b' before initialization console.log(c) //报错 Cannot access 'c' before initialization var a = 10 let b = 11 const c = 12
let b =10 和 const c =10
只保留console输出的话,会报错b is not defined
,而不是上面的例子。
- 在if语句中就算不被执行到的话,也是会被提升的。
if(true){ console.log(a) //undefined }else{ var a = 10 }
- 函数的提升
//函数语句定义函数 console.log(a); function a(){ alert("a"); } //表达式定义函数 console.log(b); var b = function(){ alert("b"); } console.log(hi);
2.var,let,const 的区别
-
let const都是块级作用域,且没有变量提升
{ let a = 10 const b = 10 } console.log(a) //报错 a is not defined console.log(b) //报错 b is not defined
-
ES6 const的特性和let其实相差不大,只是const不可修改
复合型数据是可以修改的,下面有讲
,且const声明时必须要赋值。const a; //报错 Missing initializer in const declaration const b = 10 b =20 //报错 Assignment to constant variable.
-
在同一个作用域let和const不能声明两次,而var可以。
var a = 10 var a = 10 let b = 20 let b = 20 //报错 'b' has already been declared const c = 30 const c = 30 //报错 'c' has already been declared
-
var声明的变量是存在于全局对象中的,而let和const则独立存在
var a =10 let b = 10 const c = 10 console.log(window.a) //10 console.log(window.b) //undefined console.log(window.c) //undefined
3.let,const的作用域
- 在全局声明的变量理应在块级作用域内也可以访问到,如果块级作用域存在同名变量的话会相互独立。
let a = 10 const b = 11 if(true){ let a = 20 const b = 22 console.log(a) //20 console.log(b) //22 } console.log(a) //10 console.log(b) //11
- 暂时性死区
同上,全局声明的变量理应在块级作用域内也可以访问到,但是如果写成这样呢?
只要在一个作用域内存在let声明的变量,这个变量名就会被绑定在此作用域且独立存在。let a = 10 const b = 11 if(true){ console.log(a) //报错 Cannot access 'a' before initialization console.log(b) //报错 Cannot access 'b' before initialization let a = 20 const b = 22 } console.log(a) //10 console.log(b) //11
4.const声明的变量的指向方式
- 非复合型数据(整数,浮点,字符串,布尔型)这些类型都直接指向数据,所以不可改变
- 复合型数据(数组,对象),这些类型同样也是指向数据,但是由于数组和对象的存储方式不同,数组和对象他们本身是数据,而他们下属的数据是不存储在同一地址的,所以const声明的复合型数据只能保证他们本身是不可修改的,其内部数据还是可以修改的。
//数组 const a = [] a.push(1) console.log(a) //[1] //对象 const b ={} b['aa'] = 'bb' console.log(b) //{aa: "bb"}