JavaScript 数据类型和数据结构

Programming languages all have built-in data structures, but these often differ from one language to another. This article attempts to list the built-in data structures available in JavaScript and what properties they have. These can be used to build other data structures. Wherever possible, comparisons with other languages are drawn.

动态类型

JavaScript 是 loosely typed and dynamic language. Variables in JavaScript are not directly associated with any particular value type, and any variable can be assigned (and re-assigned) values of all types:

let foo = 42;    // foo is now a number
foo     = 'bar'; // foo is now a string
foo     = true;  // foo is now a boolean
			

Data and Structure types

The latest ECMAScript standard defines nine types:

Keep in mind the only valuable purpose of typeof operator usage is checking the Data Type. If we wish to check any Structural Type derived from Object it is pointless to use typeof for that, as we will always receive "object" . The indeed proper way to check what sort of Object we are using is instanceof keyword. But even in that case there might be misconceptions.

原语值

All types except objects define immutable values (that is, values which can't be changed). For example (and unlike in C), Strings are immutable. We refer to values of these types as " primitive values ".

布尔类型

Boolean represents a logical entity and can have two values: true and false 。见 Boolean and Boolean 了解更多细节。

Null 类型

The Null type has exactly one value: null 。见 null and Null 了解更多细节。

Undefined 类型

A variable that has not been assigned a value has the value undefined 。见 undefined and Undefined 了解更多细节。

数字类型

ECMAScript has two built-in numeric types: Number and BigInt (see below).

The Number type is a double-precision 64-bit binary format IEEE 754 value (numbers between -(2 53 − 1) and 2 53 − 1). In addition to representing floating-point numbers, the number type has three symbolic values: +Infinity , -Infinity ,和 NaN (" N ot a N umber").

To check for the largest available value or smallest available value within ±Infinity , you can use the constants Number.MAX_VALUE or Number.MIN_VALUE .

Starting with ECMAScript 2015, you are also able to check if a number is in the double-precision floating-point number range using Number.isSafeInteger() Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER .

Beyond this range, integers in JavaScript are not safe anymore and will be a double-precision floating point approximation of the value.

The number type has only one integer with two representations: 0 is represented as both -0 and +0 . ( 0 is an alias for +0 .)

In the praxis, this has almost no impact. For example, +0 === -0 is true . However, you are able to notice this when you divide by zero:

> 42 / +0
Infinity
> 42 / -0
-Infinity
			

Although a number often represents only its value, JavaScript provides binary (bitwise) operators .

Caution: Although bitwise operators can be used to represent several Boolean values within a single number using bit masking , this is usually considered a bad practice. JavaScript offers other means to represent a set of Booleans (like an array of Booleans, or an object with Boolean values assigned to named properties). Bit masking also tends to make the code more difficult to read, understand, and maintain.

It may be necessary to use such techniques in very constrained environments, like when trying to cope with the limitations of local storage, or in extreme cases (such as when each bit over the network counts). This technique should only be considered when it is the last measure that can be taken to optimize size.

BigInt 类型

BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision. With BigInt s, you can safely store and operate on large integers even beyond the safe integer limit for Number s.

A BigInt is created by appending n to the end of an integer or by calling the constructor.

You can obtain the safest value that can be incremented with Number s by using the constant Number.MAX_SAFE_INTEGER . With the introduction of BigInt s, you can operate with numbers beyond the Number.MAX_SAFE_INTEGER .

This example demonstrates, where incrementing the Number.MAX_SAFE_INTEGER returns the expected result:

> const x = 2n ** 53n;
9007199254740992n
> const y = x + 1n;
9007199254740993n
			

You can use the operators + , * , - , ** ,和 % with BigInt s—just like with Number s. A BigInt is not strictly equal to a Number , but it is loosely so.

A BigInt behaves like a Number in cases where it is converted to Boolean : if , || , && , Boolean , ! .

BigInt s cannot be operated on interchangeably with Number s. Instead a TypeError will be thrown.

字符串类型

JavaScript's String type is used to represent textual data. It is a set of "elements" of 16-bit unsigned integer values. Each element in the String occupies a position in the String. The first element is at index 0 , the next at index 1 , and so on. The length of a String is the number of elements in it.

Unlike some programming languages (such as C), JavaScript strings are immutable. This means that once a string is created, it is not possible to modify it.

However, it is still possible to create another string based on an operation on the original string. For example:

Beware of "stringly-typing" your code!

It can be tempting to use strings to represent complex data. Doing this comes with short-term benefits:

With conventions, it is possible to represent any data structure in a string. This does not make it a good idea. For instance, with a separator, one could emulate a list (while a JavaScript array would be more suitable). Unfortunately, when the separator is used in one of the "list" elements, then, the list is broken. An escape character can be chosen, etc. All of this requires conventions and creates an unnecessary maintenance burden.

Use strings for textual data. When representing complex data, parse strings, and use the appropriate abstraction.

符号类型

A Symbol is a unique and immutable primitive value and may be used as the key of an Object property (see below). In some programming languages, Symbols are called "atoms".

For more details see Symbol Symbol object wrapper in JavaScript.

Objects

In computer science, an object is a value in memory which is possibly referenced by an identifier .

特性

In JavaScript, objects can be seen as a collection of properties. With the object literal syntax , a limited set of properties are initialized; then properties can be added and removed. Property values can be values of any type, including other objects, which enables building complex data structures. Properties are identified using key values. A key value is either a String or a Symbol value.

There are two types of object properties which have certain attributes: The data property and the accessor 特性。

注意: Each property has corresponding 属性。 Attributes are used internally by the JavaScript engine, so you cannot directly access them. That's why attributes are listed in double square brackets, rather than single.

Object.defineProperty() to learn more.

数据特性

Associates a key with a value, and has the following attributes:

Attributes of a data property
属性 Type 描述 Default value
[[Value]] 任何 JavaScript 类型 The value retrieved by a get access of the property. undefined
[[Writable]] Boolean false , the property's [[Value]] cannot be changed. false
[[Enumerable]] Boolean

true , the property will be enumerated in for...in loops.
另请参阅 Enumerability and ownership of properties .

false
[[Configurable]] Boolean false , the property cannot be deleted, cannot be changed to an accessor property, and attributes other than [[Value]] and [[Writable]] cannot be changed. false
Obsolete attributes (as of ECMAScript 3, renamed in ECMAScript 5)
属性 Type 描述
只读 Boolean Reversed state of the ES5 [[Writable]] attribute.
DontEnum Boolean Reversed state of the ES5 [[Enumerable]] attribute.
DontDelete Boolean Reversed state of the ES5 [[Configurable]] attribute.

Accessor property

Associates a key with one of two accessor functions ( get and set ) to retrieve or store a value, and has the following attributes:

Attributes of an accessor property
属性 Type 描述 Default value
[[Get]] Function object or undefined The function is called with an empty argument list and retrieves the property value whenever a get access to the value is performed.
另请参阅 get .
undefined
[[Set]] Function object or undefined The function is called with an argument that contains the assigned value and is executed whenever a specified property is attempted to be changed.
另请参阅 set .
undefined
[[Enumerable]] Boolean true , the property will be enumerated in for...in loops. false
[[Configurable]] Boolean false , the property can't be deleted and can't be changed to a data property. false

"Normal" objects, and functions

A JavaScript object is a mapping between keys and values . Keys are strings (or Symbol s), and values can be anything. This makes objects a natural fit for hashmaps .

Functions are regular objects with the additional capability of being callable .

Dates

When representing dates, the best choice is to use the built-in Date utility in JavaScript.

Indexed collections: Arrays and typed Arrays

Arrays are regular objects for which there is a particular relationship between integer-key-ed properties and the length 特性。

Additionally, arrays inherit from Array.prototype , which provides to them a handful of convenient methods to manipulate arrays. For example, indexOf (searching a value in the array) or push (adding an element to the array), and so on. This makes Arrays a perfect candidate to represent lists or sets.

类型化数组 are new to JavaScript with ECMAScript 2015, and present an array-like view of an underlying binary data buffer. The following table helps determine the equivalent C data types:

Type 值范围 Size in bytes 描述 Web IDL 类型 Equivalent C type
Int8Array -128 to 127 1 8-bit two's complement signed integer byte int8_t
Uint8Array 0 to 255 1 8-bit unsigned integer octet uint8_t
Uint8ClampedArray 0 to 255 1 8-bit unsigned integer (clamped) octet uint8_t
Int16Array -32768 to 32767 2 16-bit two's complement signed integer short int16_t
Uint16Array 0 to 65535 2 16-bit unsigned integer unsigned short uint16_t
Int32Array -2147483648 to 2147483647 4 32-bit two's complement signed integer long int32_t
Uint32Array 0 to 4294967295 4 32-bit unsigned integer unsigned long uint32_t
Float32Array 1.2 × 10 -38 to 3.4 × 10 38 4 32-bit IEEE floating point number (7 significant digits e.g., 1.1234567 ) unrestricted float float
Float64Array 5.0 × 10 -324 to 1.8 × 10 308 8 64-bit IEEE floating point number (16 significant digits e.g., 1.123...15 ) unrestricted double double
BigInt64Array -2 63 to 2 63 -1 8 64-bit two's complement signed integer bigint int64_t (signed long long)
BigUint64Array 0 to 2 64 -1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)

Keyed collections: Maps, Sets, WeakMaps, WeakSets

These data structures, introduced in ECMAScript Edition 6, take object references as keys. Set and WeakSet represent a set of objects, while Map and WeakMap associate a value to an object.

The difference between Map s and WeakMap s is that in the former, object keys can be enumerated over. This allows garbage collection optimizations in the latter case.

One could implement Map s and Set s in pure ECMAScript 5. However, since objects cannot be compared (in the sense of < "less than", for instance), look-up performance would necessarily be linear. Native implementations of them (including WeakMap s) can have look-up performance that is approximately logarithmic to constant time.

Usually, to bind data to a DOM node, one could set properties directly on the object, or use data-* attributes. This has the downside that the data is available to any script running in the same context. Map s and WeakMap s make it easy to privately bind data to an object.

结构化数据:JSON

JSON ( J ava S cript O bject N otation) is a lightweight data-interchange format, derived from JavaScript, but used by many programming languages. JSON builds universal data structures.

JSON and JSON 了解更多细节。

标准库中的更多对象

JavaScript has a standard library of built-in objects.

Please have a look at the reference to find out about more objects.

确定类型使用 typeof operator

typeof operator can help you to find the type of your variable.

Please read the reference page for more details and edge cases.

规范

规范
ECMAScript (ECMA-262)
The definition of 'ECMAScript Data Types and Values' in that specification.

另请参阅

Metadata

  1. JavaScript
  2. 教程:
  3. 完整初学者
    1. JavaScript 基础
    2. JavaScript 第一步
    3. JavaScript 构建块
    4. 引入 JavaScript 对象
  4. JavaScript 指南
    1. 介绍
    2. 语法和类型
    3. 控制流程和错误处理
    4. 循环和迭代
    5. 函数
    6. 表达式和运算符
    7. 数字和日期
    8. 文本格式
    9. 正则表达式
    10. Indexed collections
    11. Keyed collections
    12. Working with objects
    13. 对象模型的细节
    14. Using promises
    15. 迭代器和生成器
    16. Meta programming
    17. JavaScript 模块
  5. 中间体
    1. Client-side JavaScript frameworks
    2. 客户端侧 Web API
    3. 重新介绍 JavaScript
    4. JavaScript 数据结构
    5. 相等比较和相同
    6. 闭包
  6. 高级
    1. 继承和原型链
    2. 严格模式
    3. JavaScript 类型数组
    4. 内存管理
    5. 并发模型和事件循环
  7. 参考:
  8. 内置对象
    1. AggregateError
    2. Array
    3. ArrayBuffer
    4. AsyncFunction
    5. Atomics
    6. BigInt
    7. BigInt64Array
    8. BigUint64Array
    9. Boolean
    10. DataView
    11. Date
    12. Error
    13. EvalError
    14. FinalizationRegistry
    15. Float32Array
    16. Float64Array
    17. Function
    18. Generator
    19. GeneratorFunction
    20. Infinity
    21. Int16Array
    22. Int32Array
    23. Int8Array
    24. InternalError
    25. Intl
    26. JSON
    27. Map
    28. Math
    29. NaN
    30. Number
    31. Object
    32. Promise
    33. Proxy
    34. RangeError
    35. ReferenceError
    36. Reflect
    37. RegExp
    38. Set
    39. SharedArrayBuffer
    40. String
    41. Symbol
    42. SyntaxError
    43. TypeError
    44. TypedArray
    45. URIError
    46. Uint16Array
    47. Uint32Array
    48. Uint8Array
    49. Uint8ClampedArray
    50. WeakMap
    51. WeakRef
    52. WeakSet
    53. WebAssembly
    54. decodeURI()
    55. decodeURIComponent()
    56. encodeURI()
    57. encodeURIComponent()
    58. escape()
    59. eval()
    60. globalThis
    61. isFinite()
    62. isNaN()
    63. null
    64. parseFloat()
    65. parseInt()
    66. undefined
    67. unescape()
    68. uneval()
  9. 表达式 & 运算符
    1. Addition (+)
    2. Addition assignment (+=)
    3. Assignment (=)
    4. Bitwise AND (&)
    5. Bitwise AND assignment (&=)
    6. Bitwise NOT (~)
    7. Bitwise OR (|)
    8. Bitwise OR assignment (|=)
    9. Bitwise XOR (^)
    10. Bitwise XOR assignment (^=)
    11. Comma operator (,)
    12. 条件 (三元) 运算符
    13. Decrement (--)
    14. Destructuring assignment
    15. Division (/)
    16. Division assignment (/=)
    17. Equality (==)
    18. Exponentiation (**)
    19. Exponentiation assignment (**=)
    20. Function expression
    21. Greater than (>)
    22. Greater than or equal (>=)
    23. Grouping operator ( )
    24. Increment (++)
    25. Inequality (!=)
    26. Left shift (<<)
    27. Left shift assignment (<<=)
    28. Less than (<)
    29. Less than or equal (<=)
    30. Logical AND (&&)
    31. Logical AND assignment (&&=)
    32. Logical NOT (!)
    33. Logical OR (||)
    34. Logical OR assignment (||=)
    35. Logical nullish assignment (??=)
    36. Multiplication (*)
    37. Multiplication assignment (*=)
    38. Nullish coalescing operator (??)
    39. Object initializer
    40. 运算符优先级
    41. Optional chaining (?.)
    42. Pipeline operator (|>)
    43. 特性访问器
    44. Remainder (%)
    45. Remainder assignment (%=)
    46. Right shift (>>)
    47. Right shift assignment (>>=)
    48. Spread syntax (...)
    49. Strict equality (===)
    50. Strict inequality (!==)
    51. Subtraction (-)
    52. Subtraction assignment (-=)
    53. Unary negation (-)
    54. Unary plus (+)
    55. Unsigned right shift (>>>)
    56. Unsigned right shift assignment (>>>=)
    57. 异步函数表达式
    58. await
    59. class expression
    60. delete operator
    61. function* 表达式
    62. in operator
    63. instanceof
    64. new operator
    65. new.target
    66. super
    67. this
    68. typeof
    69. void 运算符
    70. yield
    71. yield*
  10. 语句 & 声明
    1. async function
    2. block
    3. break
    4. class
    5. const
    6. continue
    7. debugger
    8. do...while
    9. empty
    10. export
    11. for
    12. for await...of
    13. for...in
    14. for...of
    15. 函数声明
    16. function*
    17. if...else
    18. import
    19. import.meta
    20. label
    21. let
    22. return
    23. switch
    24. throw
    25. try...catch
    26. var
    27. while
    28. with
  11. 函数
    1. 箭头函数表达式
    2. 默认参数
    3. 方法定义
    4. 其余参数
    5. 自变量对象
    6. getter
    7. setter
    1. Private class fields
    2. Public class fields
    3. 构造函数
    4. extends
    5. static
  12. 错误
    1. Error: Permission denied to access property "x"
    2. InternalError: too much recursion
    3. RangeError: argument is not a valid code point
    4. RangeError: invalid array length
    5. RangeError: invalid date
    6. RangeError: precision is out of range
    7. RangeError: radix must be an integer
    8. RangeError: repeat count must be less than infinity
    9. RangeError: repeat count must be non-negative
    10. ReferenceError: "x" is not defined
    11. ReferenceError: assignment to undeclared variable "x"
    12. ReferenceError: can't access lexical declaration`X' before initialization
    13. ReferenceError: deprecated caller or arguments usage
    14. ReferenceError: invalid assignment left-hand side
    15. ReferenceError: reference to undefined property "x"
    16. SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
    17. SyntaxError: "use strict" not allowed in function with non-simple parameters
    18. SyntaxError: "x" is a reserved identifier
    19. SyntaxError: JSON.parse: bad parsing
    20. SyntaxError: Malformed formal parameter
    21. SyntaxError: Unexpected token
    22. SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
    23. SyntaxError: a declaration in the head of a for-of loop can't have an initializer
    24. SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
    25. SyntaxError: for-in loop head declarations may not have initializers
    26. SyntaxError: function statement requires a name
    27. SyntaxError: identifier starts immediately after numeric literal
    28. SyntaxError: illegal character
    29. SyntaxError: invalid regular expression flag "x"
    30. SyntaxError: missing ) after argument list
    31. SyntaxError: missing ) after condition
    32. SyntaxError: missing : after property id
    33. SyntaxError: missing ; before statement
    34. SyntaxError: missing = in const declaration
    35. SyntaxError: missing ] after element list
    36. SyntaxError: missing formal parameter
    37. SyntaxError: missing name after . operator
    38. SyntaxError: missing variable name
    39. SyntaxError: missing } after function body
    40. SyntaxError: missing } after property list
    41. SyntaxError: redeclaration of formal parameter "x"
    42. SyntaxError: return not in function
    43. SyntaxError: test for equality (==) mistyped as assignment (=)?
    44. SyntaxError: unterminated string literal
    45. TypeError: "x" has no properties
    46. TypeError: "x" is (not) "y"
    47. TypeError: "x" is not a constructor
    48. TypeError: "x" is not a function
    49. TypeError: "x" is not a non-null object
    50. TypeError: "x" is read-only
    51. TypeError: 'x' is not iterable
    52. TypeError: More arguments needed
    53. TypeError: Reduce of empty array with no initial value
    54. TypeError: X.prototype.y called on incompatible type
    55. TypeError: can't access dead object
    56. TypeError: can't access property "x" of "y"
    57. TypeError: can't assign to property "x" on "y": not an object
    58. TypeError: can't define property "x": "obj" is not extensible
    59. TypeError: can't delete non-configurable array element
    60. TypeError: can't redefine non-configurable property "x"
    61. TypeError: cannot use 'in' operator to search for 'x' in 'y'
    62. TypeError: cyclic object value
    63. TypeError: invalid 'instanceof' operand 'x'
    64. TypeError: invalid Array.prototype.sort argument
    65. TypeError: invalid arguments
    66. TypeError: invalid assignment to const "x"
    67. TypeError: property "x" is non-configurable and can't be deleted
    68. TypeError: setting getter-only property "x"
    69. TypeError: variable "x" redeclares argument
    70. URIError: malformed URI sequence
    71. Warning: -file- is being assigned a //# sourceMappingURL, but already has one
    72. Warning: 08/09 is not a legal ECMA-262 octal constant
    73. Warning: Date.prototype.toLocaleFormat is deprecated
    74. Warning: JavaScript 1.6's for-each-in loops are deprecated
    75. Warning: String.x is deprecated; use String.prototype.x instead
    76. Warning: expression closures are deprecated
    77. Warning: unreachable code after return statement
  13. 杂项
    1. JavaScript technologies overview
    2. 词汇语法
    3. JavaScript 数据结构
    4. Enumerability and ownership of properties
    5. Iteration protocols
    6. 严格模式
    7. Transitioning to strict mode
    8. Template literals
    9. 弃用特征