本文是《JavaScript 权威指南》的整理和总结
1 概述
- JavaScript 的数据类型分为两类:原始类型 (primitive type) 和对象类型 (object type)。
null
和undefined
代表了各自特殊类型的唯一成员。- 数组是带编号的有序集合对象。
- 当没有任何引用指向一个对象,解释器会自动回收它所占的内存资源。
- 不在函数内声明的变量属于全局变量。
2 数字
- JavaScript 不区分整数还是浮点数,均采用 IEEE 754 标准定义的 64 位浮点格式表示数字。
- 浮点数的范围是 ±1.7976931348623157e308~±5e-324。整数范围是 - 2^53~2^53。
- JavaScript 的数组索引以及位操作都是基于 32 位整数的。
- JavaScript 支持十进制和十六进制。
- JavaScript 的数字语法格式为:[digits][.digits][(E|e)[(+|-)]digits]
- 当数字超过 JavaScript 所能表示的范围,结果为无穷大用
±Infinity
表示。 ±Infinity
参与算术运算时,结果依然为±Infinity
。- JavaScript 在被零整除、溢出和下溢时不报错。
- 下溢是当运算结果无限接近于零并比 JavaScript 能表示的最小值还小时发生的情况,这时 JavaScript 返回 0,负数发生下溢时返回负零。
- 无穷大除以无穷大 (乘以时不会)、任意负数开平方、0 除以 0 以及算术运算符的操作数无法转化为数字时,结果将返回 NaN。
- NaN 于任何值都不相等,包括它自身。
- 负零除了作为除数时不一样外,其余都与正零值想等
3 文本
- JavaScript 的字符串是一组由 16 位值组成的不可变的有序序列。每个字符来自 Unicode 字符集。
- 字符串的长度是所含 16 位值的个数。
- 对于不能用 16 位值表示的 Unicode 则使用两个 16 位值表示,长度为 2。
- 字符串使用双引号,单引号都可。
- JavaScript 支持转义字符。
- 字符串可以作为只读数组,使用
[]
运算符访问其中的字符。
转义字符 | 含义 |
---|
\o | NUL 字符 |
\b | 退格符 |
\t | 水平制表符 |
\n | 换行符 |
\v | 垂直制表符 |
\f | 换页符 |
\r | 回车符 |
\” | 双引号 |
\’ | 单引号 |
\\ | 反斜线 |
\xXX | 由两位十六进制数 XX 指定的 Latin-1 字符 |
\uXXXX | 由四位十六进制数 XXXX 指定的 Unicode 字符 |
4 正则表达式
- 正则表达式不是 JavaScript 的基本数据类型,但也提供了直接量的写法。
- 两条斜线之间的文本构成了一个正则表达式的直接量,第二个斜线之后可以跟随多个字母,用来修饰匹配模式的含义。
/\d+/g ;//匹配所有包含一个或多个的数字实例
/^HTML/
5 布尔值
- 布尔值包含
toString()
方法,可以将值转化为字符串"true"
和"false"
。
6 null 和 undefined
null | undefined |
---|
null 是 JavaScript 的关键字 | undefined 是预定义的全局变量 |
null 表示数字、字符串或对象无值 | undefined 表示值的空缺, 例如变量未初始化、没有返回值函数的返回值、没有提供实参的形参值 |
typeof 返回"object" | typeof 返回"undefined" |
null 表示程序级别的、正常或者意料之中的值的空缺 | undefined 表示系统级别、出乎意料或类似错误的值的空缺 |
null 和undefined 都是假植 | |
== 运算符认为两者相等,只有=== 才能区分它们 | |
使用. 和[] 运算符来存取这两个值都会产生类型错误 | |
7 对象
7.1 全局对象
- 全局对象的属性是全局定义的,可以直接使用。
- JavaScript 解释器启动或者加载刷新页面时,它将创建一个新的全局对象,并给他一组定义的初始属性:
- 全局属性:
undefined
、Infinity
、NaN
- 全局函数:
isNaN()
、parseInt()
、 eval()
- 构造函数:
Date()
、RegExp()
、String()
、Object()
、Array()
- 全局对象:
Math
、JSON
- 可以在任何函数外,也就是代码最顶级,使用 JavaScript 关键字引用全局对象。
var global = this;
- 在浏览器中的所有 JavaScript 代码中,
Window
对象充当了全局对象。 - 所有定义的全局变量,都作为全局对象的属性。
7.2 包装对象
- JavaScript 的对象是复合值,是属性的集合,当属性值是函数时,称其为方法。
- 只要引用了字符串的属性,JavaScript 会通过自动调用
new String(s)
的方式转化为对象。 - 数字和布尔值也有相对应的构造函数,
Number()
和Boolean()
,null
和undefined
没有对应的包装对象。 - 包装对象不是真正的对象,只能读取,不能赋值和添加新的属性。
- 使用显示
var s = new String("sd")
创建的对象,可读写。
7.3 原始值和对象引用
- 原始值 (数字,字符串,null、布尔值、undefined) 是不可变的。
- 原始值的比较是值的比较,对象之间的比较是引用的比较,仅当引用同一对象时才相等。
7.4 类型转换
值 | 字符串 | 数字 | 布尔值 | 对象 |
---|
undefined | “undefined” | NaN | false | throws TypeError |
null | “null” | 0 | false | throw TypeError} |
true | “true” | 1 | | new Boolean(true) |
false | “false” | 0 | | new Boolean(false) |
“”(空字符串) | | 0 | false | new String(“”) |
“1.2”(非空,数字) | | 1.2(允许开始和结尾处有空格) | true | new String(“1.2”) |
“one”(非空,非数字) | | NaN | true | new String(“one”) |
0 | “0” | | false | new Number(0) |
-0 | “0” | | false | new Nunmber(-0) |
NaN | “NaN” | | false | new Number(NaN) |
Infinity | “Infinity” | | true | new Number(Infinity) |
-Infinity | “-Infinity” | | true | new Number(-Infinity) |
1 (非零) | “1” | | true | new Number(1) |
{} 任意对象 | | | true | |
[] 任意数组 | “” | 0 | true | |
[9]1 个数字元素 | “9” | 9 | true | |
[“a”] 其它数组 | 使用 join() 方法 | NaN | true | |
function(){} 任意函数 | | | true | |
# 7.4.1 对象转换为原始值
- 所有的对象,包括数组和函数,转换到布尔值时,都会转换为 true,包括
new Boolean(false)
。 - 对象通过调用
toString()
方法转换为字符串,调用valueOf()
方法转换为数字。 - JavaScript 对象到字符串的转换步骤:
- 调用
toString()
方法,如果返回一个原始值,将其转换为字符串。 - 如果没有
toString()
,或者该方法不返回一个原始值,那么将调用valueOf()
方法,然后将其返回值转换为字符。 - 如果该对象没有
toString()
和valueOf()
方法,或者这两个方法都不返回原始值,将抛出类型错误异常。
- JavaScript 对象到数字的步骤与字符串类似,只不过先尝试使用
valueOf()
,然后如有必要,再使用toString()
。 - 在 + 、==以及其它关系运算符中,对象转换原始值的过程是:先尝试调用
valueOf()
,然后调用toString()
不论原始值是否直接使用,都不会转换为数字或字符串。 - 而日期对象,则使用字符串的转换模式。
8 变量
- JavaScript 对象只有块级作用域和顶级作用域。
- 全局变量实际上是全局对象的一个属性,使用 var 声明变量时,创建的这个属性是不可配置的,无法使用
delete
运算符删除。 - 直接给未声明的变量赋值,将自动创建一个全局变量,该方式创建的对象,可以使用
delete
删除。 - 全局对象始终有定义,局部变量在声明它的函数体内,以及嵌套的函数内始终有定义。
8.1 作用域链
- 每段 JavaScript 代码,都有与之关联的作用域链,该作用域链是一个对象列表或链表,定义这个这段代码作用域中的变量。当需要查找变量 x 时,会从该链表的第一个对象开始查找。
- 在最顶层代码中,作用链有一个对象,即全局对象。在函数体内有两个对象,第一个是定义函数参数和局部变量的对象,第二个是全局对象。
- 当定义一个函数时,实际上是保存了一个作用域链,当调用该函数时,创建一个新的对象来存储它的局部变量,并将这个变量添加至保存的那个作用域链上,同时创建新的更长的表示函数调用作用域的链。
- 对于嵌套函数,每次调用外部函数时,作用域链都是不同的。