Skip to content
On this page

基础

语法

  • 区分大小写
  • 标识符
    • 第一个字符必须是字母,下划线 _ 或者 $
    • 其他字符可以是数字、字母、_$
    • 按照惯例,使用驼峰大小写形式,如myCar
    • 关键字、保留字、true、false、null不能作为标识符
  • 注释
    • // 单行注释
    • /* */ 多行注释
  • 严格模式
    • 在脚本文件开头或者函数体开头加上"use strict";
  • 语句
    • 推荐以分号 ; 结尾
    • 在控制语句中使用{ }

关键字和保留字

关键字

保留字

变量

ECMAScript变量是松散类型的,意思是变量可以用于保存任何类型的数据。每个变量只不过是一个用于保存任意值的命名占位符。

var

js
var message; //不初始化的情况下,变量会保存一个特殊值undefined
var message = 'hi';
message = 100 // 合法,但不推荐

var声明作用域

使用var操作符定义的变量会成为包含它的函数的局部变量。当使用var在函数内定义变量时,函数执行结束时变量会被摧毁。

js
function test() {
	var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!

当省略var,可以创建一个全局变量,但不推荐这么使用,在局部作用域定义全局变量很难维护。在严格模式下,会报错。

js
function test() {
	message = "hi"; // 全局变量
}
test();
console.log(message); // 'hi'

var声明提升

使用var声明的变量会自动提升到函数作用域顶部

let

let声明的范围是块作用域,而var声明的范围是函数作用域。

js
if (true) {
	var name = 'Matt';
	console.log(name); // Matt
}
console.log(name);    // Matt

if (true) {
	let age = 26;
	console.log(age);    // 26
}
console.log(age);      // ReferenceError: age没有定义

let也不允许在同个块作用域中出现冗余声明,会导致报错。嵌套使用相同的标识符是不会报错的,因为同个块中没有重复声明。

同时使用let和var声明相同标识符的变量,会报错,因为他们只是指明变量在相关作用域如何存在。

暂时性死区

let与var的另一个重要的区别,就是let声明的变量不会在作用域中被提升。

全局声明

与var关键字不同,使用let在全局作用域中声明的变量不会成为window对象的属性。

条件声明

let不能依赖条件声明,因为let声明的作用域仅限于块

js
<script>
	let name = 'Nicholas';
	let age = 36;
</script>
<script>
	// 假设脚本不确定页面中是否已经声明了同名变量
	// 那它可以假设还没有声明过
	if (typeof name === 'undefined') {
		let name;
	}
	// name被限制在if {} 块的作用域内
	// 因此这个赋值形同全局赋值
	name = 'Matt';
	try {
		console.log(age); // 如果age没有声明过,则会报错
	}
	catch(error) {
		let age;
	}
	// age被限制在catch {}块的作用域内
	// 因此这个赋值形同全局赋值
	age = 26;
</script>

for循环中的let声明

js
for (var i = 0; i < 5; ++i) {
	setTimeout(() => console.log(i), 0)
}
// 你可能以为会输出0、1、2、3、4
// 实际上会输出5、5、5、5、5

之所以会这样,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5。在之后执行超时逻辑时,所有的i都是同一个变量,因而输出的都是同一个最终值。

在使用let声明迭代变量时,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量。每个setTimeout引用的都是不同的变量实例,所以console.log输出的是我们期望的值,也就是循环执行过程中每个迭代变量的值。

js
for (let i = 0; i < 5; ++i) {
	setTimeout(() => console.log(i), 0)
}
// 会输出0、1、2、3、4

const

const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误。

最佳实践

不使用var,优先使用const,let次之。

MIT Licensed | Copyright © 2021 - 2022