基础
语法
- 区分大小写
- 标识符
- 第一个字符必须是字母,下划线
_
或者$
- 其他字符可以是数字、字母、
_
或$
- 按照惯例,使用驼峰大小写形式,如
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次之。