-
变量可以保存任何类型的数据,目前有3个关键字可以声明变量:var、let和const
-
var在所有版本中均可以使用,而let和const只能在es6及更晚的版本中使用
var关键字
声明变量名
var message; // 定义一个名为 message 的变量
var message = 'hi'; // 被定义保存字符串值 hi 的变量
var message = 'hi';
message = 100; // 合法,但不推荐修改类型
声明作用域
- 使用 var 定义的变量会成为函数作用域
function test() {
var message = 'hi' //局部变量
}
test()
console.log(message); // 出错
function test() {
message = 'hi' //全局变量
}
test()
console.log(message); // hi
- 定义多个变量
使用逗号分隔
var message = 'hi',
found = false,
age = 18
变量提升
function foo() {
console.log(age);
var age = 18;
}
foo(); // undefined
- 以上并不会报错,var 关键字会把声明的变量提升至函数作用域顶部
function foo() {
var age;
console.log(age);
age = 18;
}
foo(); // undefined
let关键字
声明作用域
if(true) {
let age = 26;
console.log(age); // 26
}
console.log(age); // ReferenceError: age is not defined
// SyntaxError: Identifier 'age' has already been declared
let age;
let age;
- 使用 let 声明的变量名会变成块级作用域,无法被外部引用。let 也不允许 同一个作用域出现冗余声明
暂时性死区
- let 声明的变量不会在作用域中被提升,let 声明之前的执行瞬间被称为 “ 暂时性死区 ”
// age 不会被提升
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 18
全局声明
- let在全局作用域中声明的变量不会成为 window 对象属性,仍然在全局作用域中发生的,相应变量仍然在生命周期内存续,避免页面重复声明同一个变量
for循环
for(var i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i);
},0)
}
- 以上输出 5、5、5、5、5,退出循环的时候,迭代变量保存的是导致循环推出的值,所有 i 都是同一个变量,因而输出的都是同一个最终值,使用 let 时,会在后台为每次迭代循环声明一个新的迭代变量。输出 0、1、2、3、4
const关键字
-
const 与 let 基本相同,const 定义的是常量,不允许修改数值
-
若引用的是一个对象,则可以修改内部的属性
声明风格及最佳实践
- 尽量不使用 var,没有块级作用域的概念,会产生变量污染
- 变量:let
- 常量:const