Skip to main content

3语言基础

语法

借鉴了 C 语言

  • 区分大小写
  • 标识符,指的是变量、函数、属性的名字
    • 第一个字符必须是 字母、下划线、或美元符号
    • 其他字符可以是字母、下划线、美元符号或数字

严格模式

"use strict";

变量

ECMAScript 变量是松散类型的,意思是变量可以用于保存任何类型的数据。每个变量只不过是一 个用于保存任意值的命名占位符。有 3 个关键字可以声明变量:var、const 和 let。其中,var 在 ECMAScript 的所有版本中都可以使用,而 const 和 let 只能在 ECMAScript 6 及更晚的版本中使用。

var

var 声明作用域

关键的问题在于,使用 var 操作符定义的变量会成为包含它的函数的局部变量。比如,使用 var 在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁:

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

这里,message 变量是在函数内部使用 var 定义的。函数叫 test(),调用它会创建这个变量并给 它赋值。调用之后变量随即被销毁,因此示例中的最后一行会导致错误。不过,在函数内定义变量时省 略 var 操作符,可以创建一个全局变量:

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

去掉之前的 var 操作符之后,message 就变成了全局变量。只要调用一次函数 test(),就会定义 这个变量,并且可以在函数外部访问到。

var 定义多个变量

如果需要定义多个变量,可以在一条语句中用逗号分隔每个变量(及可选的初始化):

var message = "hi",
found = false,
age = 29;

这里定义并初始化了 3 个变量。因为 ECMAScript 是松散类型的,所以使用不同数据类型初始化的 变量可以用一条语句来声明。插入换行和空格缩进并不是必需的,但这样有利于阅读理解。

let

let 跟 var 的作用差不多,但有着非常重要的区别。最明显的区别是,let 声明的范围是块作用域, 而 var 声明的范围是函数作用域。

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 没有定义

const

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

声明风格及最佳实践

  1. 不使用 var 有了 let 和 const,大多数开发者会发现自己不再需要 var 了。限制自己只使用 let 和 const 有助于提升代码质量,因为变量有了明确的作用域、声明位置,以及不变的值。
  2. const 优先,let 次之 使用 const 声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不 合法的赋值操作。因此,很多开发者认为应该优先使用 const 来声明变量,只在提前知道未来会有修 改时,再使用 let。这样可以让开发者更有信心地推断某些变量的值永远不会变,同时也能迅速发现因 意外赋值导致的非预期行为。

数据类型

  • 基本数据类型 Undefined、Null、Boolean、Number、String

  • 复杂数据类型 Object

typeof 操作符

因为 ECMAScript 的类型系统是松散的,所以需要一种手段来确定任意变量的数据类型。typeof 操作符就是为此而生的。对一个值使用 typeof 操作符会返回下列字符串之一:

  • "undefined"表示值未定义;
  • "boolean"表示值为布尔值;
  • "string"表示值为字符串;
  • "number"表示值为数值;
  • "object"表示值为对象(而不是函数)或 null;
  • "function"表示值为函数;
  • "symbol"表示值为符号。

注意 typeof 在某些情况下返回的结果可能会让人费解,但技术上讲还是正确的。比如,调用 typeof null 返回的是"object"。这是因为特殊值 null 被认为是一个对空对象的引用。

Undefined 类型

Undefined 类型只有一个值,就是特殊值 undefined。 undefined 派生自 null,因此用 == 比较返回 true 当使用 var 或 let 声明了变量但没有初始化时,就相当于给变量赋予了 undefined 值:

let message;
console.log(message == undefined); // true

Null 类型

Null 类型同样只有一个值,即特殊值 null。逻辑上讲,null 值表示一个空对象指针,这也是给 typeof 传一个 null 会返回"object"的原因:

let car = null;
console.log(typeof car); // "object"

null 是一个假值。因此,如果需要,可以用更简洁的方式检测它。不过要记住,也有很多其他可 能的值同样是假值。所以一定要明确自己想检测的就是 null 这个字面值,而不仅仅是假值。

let message = null;
let age;
if (message) {
// 这个块不会执行
}
if (!message) {
// 这个块会执行
}

if (age) {
// 这个块不会执行
}
if (!age) {
// 这个块会执行
}

Boolean 类型

Boolean(布尔值)类型是 ECMAScript 中使用最频繁的类型之一,有两个字面值:true 和 false。 这两个布尔值不同于数值,因此 true 不等于 1,false 不等于 0。

|  数据类型   | 转换为 true 的值  | 转换为 false 的值  |
| ---- | ---- | ---- |
| Boolean | true | false |
| String | 非空字符串 | ""(空字符串) |
| Number | 非零数值(包括无穷值) | 0、NaN(参见后面的相关内容) |
| Object | 任意对象 | null |
| Undefined | N/A(不存在) | undefined |

Number 类型

最基本的数值字面量格式是十进制整数,直接写出来即可:

let intNum = 55; // 整数
let octalNum1 = 070; // 八进制的 56
let octalNum2 = 079; // 无效的八进制值,当成 79 处理
let octalNum3 = 08; // 无效的八进制值,当成 8 处理

浮点数

指的是数值中包含一个小数点,并且小数点后面至少有一位数字

数值转换

有 3 个函数可以把非数值转换为数值

  • Number() 可以用于任何数据类型
  • parseInt() 专门用于字符串转数值,用于解析整数
  • parseFloat() 专门用于字符串转数值,用于解析浮点数

String 类型

字符字面量

字符串数据类型包含一些字符字面量,用于表示非打印字符或有其他用途的字符,

|  字 面 量  | 含 义 |
| ---- | ---- |
| \n | 换行 |
| \t | 制表 |
| \b | 退格 |
| \r | 回车 |
| \f | 换页 |
| \\ | 反斜杠(\) |
| \' | 单引号('),在字符串以单引号标示时使用,例如'He said, \'hey.\'' |
  • 数值、布尔值、对象、字符串值本身 都有 toString()方法,用于转为字符串
  • undefined 和 null 没有 toString()方法,但可以使用 String()方法

Symbol 类型

Object 类型

  • 对象其实就是一组数据与功能的集合
  • 使用 Object()构造函数创建对象
var obj = new Object(); // 同 obj = {}

每个对象实例都有下列属性和方法

  • constructor 指向用于创建当前对象的构造函数 。(对于上面例子而言,就是 Object())
  • hasOwnProperty(propertyName) 用于检查给定属性是否在当前对象实例中
  • isPrototypeOf(Object) 用于检查传入的对象是否是当前对象的原型
  • propertyIsEnumerable(propertyName) 用于检查给定的属性是否能够使用 for-in 来枚举
  • toLocaleString() 返回对象的字符串表示,该字符串与执行环境的地区对应
  • toString() 返回对象的字符串表示
  • valueOf() 返回对象的字符串、数值、布尔值表示。通常与 toString()返回值相同

所有对象都有以上属性和方法

操作符

一元操作符

  • '++'
  • '--'

前置与后置的区别是与其他数运算时,前置会先执行递增(减)再与其他数运算,后置会先与其他数运算再对自身执行递增(减)

布尔操作符

  • 与 (&&) 短路操作,即如果第一个操作数能决定结果,就不会对第二个操作数求值
  • 或 (||) 短路操作,即如果第一个操作数能决定结果,就不会对第二个操作数求值
  • 非 (!) 先使用 Boolean()转成布尔值再取反

语句(也称流控制语句)

if-else

###do-while 后测试循环语句,在对表达式求值之前,循环体内的代码至少会被执行一次

var i = 0;
do {
i += 2;
} while (i < 10); // 只要i小于10就会一直循环

while

前测试语句

var i = 0;
while (i < 10) {
i += 2;
} // 只要i小于10就会一直循环

for

使用 while 循环做不到的,使用 for 循环同样做不到。就是说,for 循环只是把与循环有关的代码集合在一个位置

for (初始化; 条件; 循环后执行) {
// ...
}

break 立即退出循环 continue 退出当前单次循环

for- in 用来枚举对象的属性

函数

任何函数都可以在任何时候返回任何值 未指定返回值的函数会返回一个 undefined 通过 arguments 访问参数,它是一个类数组