var关键字
1、var声明作用域:
(1)使用var操作符定义的变量,会成为包含它的函数的局部变量。
例:
function test() {
var name = "lihua" //局部变量
}
test()
console.log(name) //出错 (name为test函数的局部变量)
(2)在函数内定义变量时省略var操作符,可以创建一个全局变量。
例:
function test1(){
name="hi"//全局变量
}
test1()
console.log(name)
2、var声明提升
使用var时,关键字声明的变量会自动提升到函数作用域顶部:
以下代码之所以不报错是因为var关键字的变量提升:
function foo(){
console.log(age)
var age=26 //变量提升
}
foo() //undefined
以上代码运行时被看成等价于如下代码:
function foo(){
var age=26
console.log(age)
}
foo() //undefined
let关键字
1、let声明作用域
let和var作用差不多,但有非常重要的差别。let作用域的范围是块作用域,而var声明范围是函数作用域。
例:
var正常运行
if(true){
var name="marry";
console.log(name)//marry
}
console.log(name)//marry
let报错,因为let作用域仅限于该块内容
if(true){
let age=10;
console.log(age) //10
}
console.log(age) //ReferenceError :age is not defined
2、暂时性死区
let与var另外差别,let声明的变量不会在作用域中被提升
// var name会被提升
console.log(name) //undefined
var name="marry"
// 相当于
var name
console.log(name)
name="marry"
// let name不会被提升
console.log(name)
let name="marry"//ReferenceError age没有被定义
3、全局声明
var全局声明会成为window对象的属性,let不会
例:
var name="marry"
console.log(window.name) //marry
let age="10"
console.log(window.name)//undefined
4、for循环中let声明
var迭代变量会渗透到循环体外部,退出循环时,迭代保存的是导致退出循环的值(在这里是5),所有i都是同一个值。
for(var i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
},100)
}
// 输出 5、5、5、5、5
let迭代变量作用域仅限于for循环内部
for(let i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
},100)
}
// 输出 0、1、2、3、4
5、let不允许重复声明
例:
let name="marry"
let name="jack" //报错Identifier
const关键字
1、const的行为与let基本相同,重要区别是它声明变量时用它声明变量时必须同时初始化变量,且尝试修改const声明会导致运行错误。
例:
const age=26
age=36//TypeError 给常量赋值 修改报错
2、const也不允许重复声明
例:
const name="marry"
const name="jack" //报错Identifier
3、const声明也是块
例:
const name="marry"
if(true){
const name="haha"
}
console.log(name) //marry
4、const 声明一个不会被修改的for循环变量
for(const key in {a:1,b:2}){
console.log(key)
}
输出 a,b
总结
ES6中,最好不使用var,const优先,因为const可以让浏览器强制保持不变,也可以让静态代码分析工具提前发现不合法的赋值操作,let次之。本次分享若有错误之处,欢迎大家指正。