数据结构
编程语言都有内置的数据结构,但各种编程语言的数据结构常有不同之处。
动态类型
JavaScript 是一个弱类型的动态语言,在定义变量时不会与特定的数据类型进行关联,这使得它可以用任何类型的数据进行定义和重定义:
var foo = 42; // 一开始 `foo` 是数字类型
foo = 'bar'; // 这时 `foo` 是字符串类型
foo = true; // 最后 `foo` 变成了布尔类型
数据类型
在 JavaScript 中,数据类型可以分为「原始类型」和「引用类型」两大类,其中原始类型也叫「基本类型」。
原始类型
原始类型的数据不是一个对象,并且没有对其本身做修改的方法,它们都是不可变的。
目前为止,内置的原始类型有以下 7 种:
类型 | 说明 |
---|---|
String |
字符串 |
Number |
数字 |
BigInt |
- |
Boolean |
表示一个逻辑实体,有 true 和 false 两个值 |
Symbol |
- |
Null |
表示变量为空,只有 null 一个值 |
Undefined |
表示变量未定义/未被赋值,只有 undefined 一个值 |
虽然原始类型的数据不是一个对象,并且没有对其本身做修改的方法,但 JavaScript 中对除了 null
和 undefined
之外的原始类型的值都提供了相应的对象,称为「原始类型包装对象」:
原始类型的数据本身没有可供调用的方法,但如果去调用了,实际调用的是其包装对象的原型定义的方法:
'foo'.toUpperCase(); // `toUpperCase` 定义于字符串的包装对象 `String` 的原型上
引用类型
引用类型的数据就是对象,函数和数组也是对象,只不过相对特殊一点。一个对象就是内存中可以被标识符所引用的一块区域。
除了上面提到的原始类型的包装对象,JavaScript 中还提供了很多种其他的标准内置对象,下面只简单介绍些与基础数据处理相关的。像队列、链表等常用的但 JavaScript 没有提供的数据结构,可以使用已提供的内置对象自己实现。
索引集合
用索引来排序的数据集合叫做「索引集合」,主要有数组和类型数组。其中,类型数组又细分为:
类型 | 值范围 | 字节大小 | 说明 |
---|---|---|---|
Int8Array |
-128~127 | 1 | 8-bit two's complement signed integer |
Uint8Array |
0~255 | 1 | 8-bit unsigned integer |
Uint8ClampedArray |
0~255 | 1 | 8-bit unsigned integer (clamped) |
Int16Array |
-32768~32767 | 2 | 16-bit two's complement signed integer |
Uint16Array |
0~65535 | 2 | 16-bit unsigned integer |
Int32Array |
-2147483648~2147483647 | 4 | 32-bit two's complement signed integer |
Uint32Array |
0~4294967295 | 4 | 32-bit unsigned integer |
Float32Array |
1.2x10-38~3.4x1038 | 4 | 32-bit IEEE floating point number ( 7 significant digits e.g. 1.1234567) |
Float64Array |
5.0x10-324~1.8x10308 | 8 | 64-bit IEEE floating point number (16 significant digits e.g. 1.123...15) |
BigInt64Array |
-263~263-1 | 8 | 64-bit two's complement signed integer |
BigUint64Array |
0~264-1 | 8 | 64-bit unsigned integer |
键控集合
用键来排序的数据集合叫做「键控集合」:
结构化数据
类型检测
在 JavaScript 中想要检测变量的数据类型,可以通过 typeof
、Object.prototype.toString()
和 instanceof
这三种方式。
typeof
通过 typeof
可以粗略地判断一个变量是原始类型还是引用类型,适合不需要知道引用类型的数据具体是什么对象的场景使用。其返回值,可能有以下几种结果:
类型 | 结果 |
---|---|
String |
"string" |
Number |
"number" |
BigInt |
"bigint" |
Boolean |
"boolean" |
Symbol |
"symbol" |
Null |
"object" |
Undefined |
"undefined" |
Function |
"function" |
其他任何对象 | "object" |
typeof null
的返回值是 "object"
虽然让人费解,但其是有历史原因的。
Object.prototype.toString()
使用 Object.prototype.toString.call(foo)
或 Object.prototype.toString.apply(foo)
会返回一个 "[object Type]"
形式的字符串,其中 Type
就是对象的类型,根据这个可以比 typeof
更精确地检测变量的类型。
然而,需要注意的是,此方式获取到的是对象的类型,而不是像 typeof
那样直接返回的数据类型。当被检测的变量是一个不是 undefined
或 null
的原始类型时,实际操作的是其对应的包装对象。
instanceof
从名字就可以看出,instanceof
是用来判断变量是否为某个构造函数的实例。因此,instanceof
只能用于对象,而不能对原始类型使用:
console.log(123 instanceof Number); // 输出 `false`
类型转换
在使用 +
运算符时,如果左右两边有字符串,则另外一边以字符串的形式进行拼接,否则进行加法运算。如果是其他的数学运算符,会转换为数字。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_Types#Data_type_conversion