《JavaScript高级程序设计》学习笔记(一)- var、let 和 const
变量声明
ECMAScript 变量是松散类型的,变量可以用于保存任何类型的数据,每个变量只不过是一个用于保存任意值的命名占位符。有三个关键字可以声明变量:var
、let
和const
。其中var
在所有版本中都可以使用,而let
和const
只能在 ECMAScript6 及之后版本中使用。
1. var
关键字
var message
定义一个名为
message
的变量,可以用于保存任何类型的值。在不初始化的情况下,变量会保存一个特殊值undefined
。var message = 'hi'
message = 100 // 合法,但不推荐
在声明的同时可以进行初始化。变量的初始化只是简单的赋值,并不标识变量类型,之后不仅可以改变变量保存的值,还可以改变值的类型。
1.1
var
声明作用域
使用var
操作符在全局作用域中声明的变量将成为window
对象的属性。var name = 'Stan'
console.log(window.name) // Stan
使用
var
操作符定义的变量会成为包含它的函数的局部变量。function test() {
var message = 'h1' // 局部变量
}
test() // 函数调用之后其中的局部变量即被销毁
console.log(message) // error
在函数内定义变量时省略
var
操作符,将创建一个全局变量。(在严格模式下将抛出ReferenceError
)function test() {
message = 'hi' // 全局变量
}
test()
console.log(message) // hi
可以在一条语句中定义多个变量,并进行初始化(可选的)。
var message = 'hi',
age = 20,
found = false
1.2
var
声明提升
使用var
操作符声明的变量会自动提升到函数作用域的顶部。变量提升(hoist)指的是将变量声明提升到函数作用域的顶部。function foo() {
console.log(age)
var age = 20
}
foo() // undefined/* 等价于 */
function foo() {
var age
console.log(age)
age = 20
}
【《JavaScript高级程序设计》学习笔记(一)- var、let 和 const】此外,可以多次使用
var
声明同一个变量,而let
和const
均不允许在作用域内出现冗余声明。混用三个操作符也要遵从操作符的规则。var age = 20
var age = 21
var age = 22
console.log(age) // 22let name
let name // SyntaxErrorvar name = 'xiaoming'
var name = 'xiaohong' // OK
let name // SyntaxErrorlet age
var age // SyntaxError
2.
let
关键字let
和var
的作用类似,主要区别在于,let
声明的范围是块作用域,而var
声明的范围是函数作用域。if (true) {
var name = 'Stan'
console.log(name) // Stan
}
console.log(name) // Stanif (true) {
let age = 20 // 作用域仅限于当前块
console.log(age) // 20
}
console.log(age) // ReferenceError
JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同标识符不会报错,因为同一个块中没有重复声明。
var name = 'xiaoming'
let age = 20
console.log(name) // xiaoming
console.log(age) // 20
if (true) {
var name = 'xiaohong'
let age = 19
console.log(name) // xiaohong
console.log(age) // 19
}
2.1 暂时性死区
let
和var
的另一个重要区别在于,let
声明的变量不会在作用域内被提升。console.log(name) // undefined
console.log(age) // ReferenceError
var name = 'xiaoming'
let age = 20
在解析代码时,JavaScript 引擎也会注意到出现在块后部的
let
声明,但在此之前不能以任何方式来引用未声明的变量,否则将抛出ReferenceError
。在let
声明前的执行瞬间称为暂时性死区(temporal dead zone)。2.2 全局声明 与
var
关键字不同,使用let
在全局作用域中声明的变量不会成为window
对象的属性。let age = 10
console.log(window.age) // undefined
2.3 条件声明 JavaScript 不支持条件声明。
使用
try/catch
语句或typeof
操作符也无法解决,因为条件块中let
声明的作用域仅限于该块。if (typeof name === 'undefined') {
let name // name的作用域仅限于此块作用域
}
name = 'Stan' // 无法达到目的,形同全局赋值
try {
console.log(age) // 若未声明age,则会报错
} catch (error) {
let age // age的作用域仅限于此块作用域
}
age = 20 // 无法达到目的,形同全局赋值
2.4
for
循环中的let
声明(包括for-in
和for-of
循环)
for (var i = 0;
i < 5;
i++) {}
console.log(i) // 5
for (var j = 0;
j < 5;
j++) {
setTimeout(() => console.log(j))
}
// 5 5 5 5 5
for (let m = 0;
m < 5;
m++) {}
console.log(m) // ReferenceError
for (let n = 0;
n < 5;
n++) {
setTimeout(() => console.log(n))
}
// 1 2 3 4 5
3.
const
关键字const
关键字与let
基本相同,唯一重要的区别在于使用const
关键字声明时必须同时初始化变量,且不能修改该变量的值,否则将抛出SyntaxError
。const
声明的变量只适用于它指向的变量的引用,即若const
变量引用一个对象,修改该对象内部的属性并不违反const
的限制。4. 声明风格及最佳实践
const
优先,let
次之,不使用var
。推荐阅读
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 《跨界歌手》:亲情永远比爱情更有泪点
- 诗歌:|诗歌: 《让我们举起世界杯,干了!》
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 人间词话的智慧
- 《一代诗人》37期,生活,江南j,拨动心潭的一泓秋水
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术
- 书评——《小行星》