简述
- var
- 作用域:函数;可以重新分配;可以修改;同一作用域可以重复声明
- let
- 作用域:块级;可以重新分配;可以修改;同一作用域不能重复声明
- const
- 作用域:块级;不能重新分配;可以修改;同一作业域不能重复声明
详细介绍
var
var没有块级作用域,由它声明的变量的作用域要么是一个函数要么就是全局的
关于声明变量和非声明变量
- 声明变量的作用域限制在声明位置的上下文中,非生命变量的作用域总是全局的
- 声明变量在任何代码执行前创建,而非声明代码只有在赋值时被创建
声明变量上下文环境中的不可配置属性,而非声明变量是可配置属性
严格模式下非声明变量会出错变量提升
变量的声明会被提升到其作用域的开头被处理,这就是变量提升。但是此时的处理只是声明了变量,对于var声明的变量而言,会在此时被赋值为undefine,而对变量的赋值只有在执行到该声明语句时才会被执行
console.log(a);//undefine
var a=2;
console.log(a);//2
多个变量的初始化
function f(){
var x=y=2;//x在函数中被声明,而y是全局变量;
};
let
let与var一样声明时同样会有变量提升,但不同的是此时变量是无法访问的,如果此时访问变量就会报错,这也就是所谓的暂存死区的问题
更多关于暂存死区的问题请访问这里(要注意的是声明变量时,一条语句中依然是顺序执行的)
console.log(a);//ReferenceError
let a=2;
console.log(a);//2
const
const声明的变量相当于一个常量,但它并不是不可改变的,当你声明的是一个数组或对象时
const x=b[];
x=a[];//error
const x=b[];
b.push(1);
console.log(x[0]);//1
const obj={name:"John"};
obj.age=20;
obj.name="Peter";
console.log(obj.name+obj.age);//"Peter20"
函数的声明
函数同样也会提升,可以在函数定义之前使用函数
var b=foo();
console.log(b);//1
console.log(foo);//function foo
function foo(){
var a=4;
return 1;
};
var foo=2;
console.log(foo);//2
从上面的代码可以看出函数的提升优先于变量