1.语法
1.1 标识符
标识符,就是变量、函数、属性或函数参数的名称。标识符按照ECMAScript惯例,采用驼峰命名法,由一或多个下列字符组成:
- 第一个字符必须是一个字母、下划线(_)或美元符号($);
- 剩下的其他字符可以是字母、下划线、美元符号或数字。
1.2 语句
ECMAScript 中的语句以分号结尾。省略分号就意味着由解析器确定语句在哪结尾。加分号有助于防止因为省略造成的问题,也便于开发者通过删除空行来压缩代码(如果没有结尾的分号,只删除空行,则会导致语法错误),同时加分号也有助于在某些情况下提升性能。
2.关键字与保留字
关键字不能用作标识符或属性名。
3.变量
ECMAScript 变量是松散类型的,意思是变量可以用于保存任何类型的数据。每个变量都是一个用于保存任意值的命名占位符。有 3 个关键字可以声明变量:var、const 和 let。其中const 和 let 只支持 ECMAScript 6。
3.1 var 关键字
var message = "hi";
这行代码定义了一个名为 message 的变量,并为其赋值。这里,message 被定义为一个保存字符串值 hi 的变量。
1. var 声明作用域
var声明作用于全局或函数内,声明在函数内的作用于该函数内,声明于函数外的作用于全局。使用 var 操作符定义的变量会成为包含它的函数的局部变量。比如,使用 var在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁:
function test() {
var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!
在函数内定义变量时省略 var 操作符,可以创建一个全局变量,但不推荐这么做。在局部作用域中定义的全局变量很难维护:
function test() {
message = "hi"; // 全局变量
}
test();
console.log(message); // "hi"
如果需要定义多个变量,可以在一条语句中用逗号分隔每个变量。
var message = "hi",
found = false,
age = 29;
2. var 声明提升
使用var关键字声明的变量会自动提升到函数作用域顶部:
function foo() {
console.log(age);
var age = 26;
}
foo(); // undefined
以上代码等价于:
function foo() {
var age;
console.log(age);
age = 26;
}
foo(); // undefined
3.2 let 声明
let 声明的范围是块作用域,而 var 声明的范围是函数作用域(函数作用域是指在在函数内部声明的只能在这个函数内部访问的变量,块作用域是函数作用域的子集)。let 不允许同一个块作用域中出现冗余声明。这样会导致报错:
let age;
let age; // SyntaxError;标识符 age 已经声明过了
1.暂时性死区
由于 let 声明的变量不会在作用域中被提升,即:let(const)声明的变量不能在声明位置前使用。在"预处理"时,所有的声明被“注册”,var声明的变量会分配一个初始值(undefined),而let不会,只有执行到声明语句时,let声明的变量才会被初始化,而未初始化的变量不能使用。从let变量作用域顶部到声明位置被称作“暂存死区”。
2. 全局声明
使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)。
var name = 'Matt';
console.log(window.name); // 'Matt'
let age = 26;
console.log(window.age); // undefined