目录
ECMAScript变量可以用于保存任何类型的数据,其中可以使用三个关键字来定义数据:var、let、const。注意:var在ES的所有版本中都可以使用,const和let只能在ES6及更晚的版本中使用。接下来我们看看三者的特性与区别。
一、var
使用实例,定义变量:
//定义单个变量
var name; // 没有初始化
var message="hi"; // 定义时同时初始化
//定义多个变量
var message,found,age; // 没有初始化
var message = "hi",
found = false,
age = 29; // 定义时同时初始化
1、var作用域
var声明的变量在一个函数作用域中有效。如下图,在test函数中可以访问到message这个变量,但是在函数体外访问message就会出错。
var定义的是一个局部变量,那么在函数退出时var所定义的变量就会被销毁。因此示例中的最后一行会导致错误。
function test() {
var message = "hi";
console.log(message); //answer is : hi
}
test();
console.log(message); // 出错!
2、var声明提升
声明提升是指:变量的声明会自动提升到函数作用域顶部。
如下图:age的值是undefined,而不是报错,这就是用到了变量声明提升。
function foo() {
console.log(age);
var age = 26;
}
foo(); // undefined
上面的代码等价于
function foo() {
var age; // 未初始化时age即为undefined,故输出为undefined
console.log(age);
age = 26;
}
foo(); // undefined
未初始化时age值为undefined,故输出为undefined。
以上就是所谓的提升。
另外:var可以重复声明同一个变量,变量的值则是后来者居上,最后给变量赋的值就是变量最终的值。
实例如下:
function foo() {
var age = 16;
var age = 26;
var age = 36;
console.log(age);
}
foo(); // 36
二、let
1、let作用域
let声明的范围是块作用域。在定义变量的块以外则不可访问。
什么叫块?通常我们把用一对花括号(“{”,”}“)包裹起来的部分叫做一个块
if (true) {
let age = 26;
console.log(age); // 26
}
console.log(age); // ReferenceError: age没有定义
与var不同,let不允许同一个块作用域中出现重复声明
2、暂时性死区
也就是说let声明的变量不会在作用域中被提升
// name会被提升
console.log(name); // undefined
var name = 'Matt';
// age不会被提升
console.log(age); // ReferenceError:age没有定义
let age = 26;
那么在let声明之前的执行瞬间被称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出ReferenceError。
3、全局声明
与var关键字不同,使用let在全局作用域中声明的变量不会成为window对象的属性(var声明的变量则会)。
var name = 'Matt';
console.log(window.name); // 'Matt'
let age = 26;
console.log(window.age); // undefined
三、const
const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误。也就是说const定义的是一个不能修改值的常量。
既然const与let基本相同,那么const具有let一样的特性:块作用域、暂时性死区、不能重复声明等。
const name = 'Matt';
const name = 'Nicholas'; // SyntaxError
如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制
const person = {};
person.name = 'Matt'; // ok
四、总结
建议:不使用var;const优先,let次之。因为变量有了明确的作用域、声明位置,以及不变的值,有助于提升代码质量。只在提前知道未来会有修改时,再使用let。
作用域 | 变量提升 | 重复定义 | 声明时需初始化 | 值可修改 | |
var | 函数作用域 | 存在变量提升 | 允许 | 不强制 | 可修改 |
let | 块作用域 | 存在暂时性死区 | 不允许 | 不强制 | 可修改 |
const | 块作用域 | 存在暂时性死区 | 不允许 | 强制 | 不可修改 |