定义:变量可以用于保存任何类型的数据,是一个保存任意值的命名占位符。其中var在ES的所有版本中都能使用,let、const只能在ES6及其以后的版本使用。
var声明:
var example ;
//声明未赋值:example是undefined
var example = 'q';
example = 100;//合法;但example即被更改了值,也更改了值的类型。
var声明作用域:使用var在Function函数内定义变量,会使其成为函数作用域中的局部变量,这就意味着变量会在函数调用结束后被销毁:
function test(){
var example = 'q';
}
test();
console.log(example);//报错
如果在函数内定义变量时省略var操作符,可以创建一个全局变量:(这种写法在严格模式下,是不允许的)
//会自动在全局作用域中补上:var example;
function test1(){
example = 'q';
}
test1();
console.log(example);//'q'
var声明多个变量:在严格模式下,不能定义eval和arguments的变量,否则会导致语法错误。
var example = 'q',
state = flase,
age = 10,
var声明提升:所谓的声明提升,就是把函数作用域内的声明拉到函数作用域顶部。
function test2(){
console.log(age)
var age = 19;
}
test2();//undefined
之所以不报错,是因为ECMAScript在运行时把它看成等价于如下代码:
function test2(){
var age;
console.log(age)
age = 19;
}
test2();//undefined
可重复声明同一变量:
function test3(){
var age = 10;
var age = 20;
var age = 19;
}
test3();//19
let声明:
let声明作用域:let与var明显的区别之一,let声明的范围是块作用域,而var声明的范围是函数作用域。
if(true){
var name = 'Matt';
console.log(name);//Matt
};
console.log(name);//Matt
if(true){
let age = 20;
console.log(age);//20
};
console.log(age);//ReferenceError:age没有定义
上面代码中,age之所以不能在if块作用域外被引用,是因为它的作用域仅限于该块内部。if块作用域是外部函数作用域的子集。
不可冗余声明:let不能在同一作用域中重复声明变量,嵌套使用相同变量不会报错。
let age =1;
let age =18;//SyntaxError:标识符age已经声明过
//同一作用域中,不会因为混用而不报错
let age =1;
var age =18;//SyntaxError
暂时性死区:let与var的区别之二,就是let声明的变量不会在作用域中被提升。
//var被提升
console.log(age);//undefined
var age = 19;
//let不被提升
console.log(age);//ReferenceError:age没有定义
let age = 19;
JS引擎在解析代码时,也会注意到后面块出现的let声明,只是没有在声明之前不能以任何方式来引用未被声明的变量;因此,在let声明之前的瞬间执行叫”暂时性死区“,在此阶段引用后面的才声明的变量都会抛出ReferenceError错误。
let全局声明:let与var的区别之三,就是var在全局作用域中声明的变量会成为window对象的属性;而let不会。
var name = 'Li';
console.log(window.name);//'Li'
let name = 'Li';
console.log(window.name);//undefined
const关键字:
const与let基本相同,唯一重要的区别,就是const声明时必须初始化(赋值),且如果尝试修改const声明的变量会导致运行时错误;const也不允许重复声明,声明的作用域也是块。
const age = 12;
age = 13;//TypeError
const name = 'Li';
if(true){
const name = 'Zhang';
}
console.log(name);//'Li'
const声明的限制只适用于它指向的变量的引用。也就是说,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制。
const personObj={
name:'张三',
}
personObj.name="李四";
console.log(personObj.name);//"李四"
使用风格:优先使用const,let次之,尽量减少var的使用。