var关键字
var的声明作用域
使用var操作符定义的变量会成为包含它的函数的局部变量。也就是说,我们使用var在一个函数内部定义了一个变量,这个变量会再函数退出时销毁。
function lianxi(){
var a=1;//a是局部变量
}
lianxi();//调用函数
console.log(a) //有错误
在上面代码中a是局部变量,调用函数lianxi给a赋值,调用之后变量被销毁,所以最后一行打印a会出错。如果我们要在函数内定义变量时省略var关键字,就可以创建一个全局变量:
function lianxi(){
a=1;//a是全局变量
}
lianxi();//调用函数
console.log(a) // 1
去掉var后,a变成了全局变量,只要调用一次lianxi函数,就会定义这个变量,并可以在函数外部访问到。
虽然可以省略var定义全局变量,但是不推荐这么写,在局部作用域中定义的全局变量很难维护,也会造成很多不必要的麻烦(我们不能一下子断定省略var是不是有意为之),在严格模式下,如果这样给未声明的变量赋值会导致ReferenceError
var的声明提升
使用var定义的变量会自动提升到函数作用域的顶部。
function foo(){
console.log(aa)
var aa=12
}
foo();//undefined
使用var定义aa上面变量没有报错,是因为上面代码再运行时ECMAScript认为它等同于以下代码:
function foo(){
var aa;
console.log(aa)
aa=12
}
foo();//undefined
这就是所谓的变量提升,即使我们使用多次var声明同一个变量也没问题,最后一次声明会覆盖前面的。
let声明
let声明作用域
let和var的作用差不多,但是有着非常重要的区别,var是函数作用域,let声明是块级作用域。块级作用域是函数作用域的子集,适用于var作用域的限制仍旧适用于let。
暂时性死区
let和var另一个重要的区别就是let声明的变量不会在作用域中被提升。
在解析代码时,在解析let声明之前不能以任何方式来引用未声明的变量,在let声明之前的执行瞬间被称为“暂时性死区”,在这时候引用任何后面才声明的变量都会有ReferenceError
全局声明
与var关键字不同,let在全局作用域中声明的变量不会成为Windows对象的属性,var会。
var name='zs'
console.log(window.name) //zs
let age=11
console.log(window.age) //undefined
不过,let声明仍然是在全局作用域中发生的,相应变量会在页面的生命周期内存续。
const声明
const的行为与let基本相同,唯一一个重要区别是用它声明变量的同时必须变量初始化,如果尝试修改const声明的变量会导致运行错误。
const声明的限制只适用于她它指向的变量的引用,也就是说,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制。
const person={};
person.name='zs'//ok
总结
var | let | const | |
---|---|---|---|
重复声明 | 允许 | 不允许 | 不允许 |
变量提升 | 有 | 没有 | 没有 |
暂时性死区 | 没有 | 有 | 有 |
window对象的属性和方法 | 有 | 没有 | 没有 |
作用域 | 函数作用域 | 块级作用域 | 块级作用域 |