Javascript 数据结构
编程语言都具有内建的数据结构,但各种编程语言的数据结构常有不同之处。 本文尝试展现 JavaScript 语言中内建的数据结构及其属性,它们可以用来构建其他的数据结构, 同时尽可能的描述 JavaScript 数据结构与其他语言的不同之处。
ECMAScript 标准定义了 6 种数据类型:
- Number
- String
- Boolean
- Null
- Undefined
- Object
在下面的章节, 我们将看到这些数据类型如何被用于表现数据以及组合实现更复杂的数据结构。
原始值
对象以外的所有类型都定义不变的值。 特别是字符串是不可变的(与 C 语言不同)。 我们称这些类型的值为“原始值”。 在下面的 Strings(字符串)章节会更详细的解释。
布尔值,null 和 undefined
在这些类型里面,只有4种类型被定义成常量:true,false
,null
,和undefined
。 因为它们是常量,所以不能使用它们来呈现丰富的数据(或数据结构)。
数字
依据 ECMAScript 标准,只有一种数字类型:它是一个基于IEEE 754标准的双精度64位二进制格式的值。所以它并没有为整数给出一种特定的类型。 除了能够表示浮点型的数值之外,还有一些带符号的值:+Infinity,-Infinity
,和 NaN
(非数值)。
尽管一个数字常常仅代表它本身的值,但JavaScript提供了一些位操作符。 这些位操作符和一个单一数字通过位操作可以用来表现一些布尔值。但这通常被认为是一个不好的做法,因为 JavaScript 提供了其他的手段来表示一组布尔值(如一个布尔值数组或一个布尔值分配给命名属性的对象)。 在一些非常受限的情况下,可能需要用到这些技术,比如试图应付本地存储的存储限制orin extreme cases when each bit over the network counts. This technique should only be considered when it is the last thing that can be done to optimize size.
字符串
不像 C 语言, JavaScript 字符串是不可更改的。这意味着字符串一旦被创建,就不能被修改。无论如何,它仍然可以通过新创建一个基于操作原字符串的新字符串(这么绕口),例如:通过String.substring, String.substr, String.slice, String.concat 等操作来修改原字符串时。
Beware of "stringly-typing" your code!
It can be tempting to use strings to represent complex data. They have a couple of nice properties:
- It's easy to build complex strings with concatenation.
- Strings are easy to debug (what you see printed is always what is in the string).
- Strings are the common denominator of a lot of APIs (input fields, local storage values,
XMLHttpRequest
responses when usingresponseText
, etc.) and it can be tempting to only work with strings.
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 becomes a maintenance burden which does not exist when the right tool for the right job is used.
It is recommended to use strings for textual data and symbolic data, but to parse strings and use the right abstraction for what it is supposed to represent otherwise.
对象
在Javascript里,对象可以被看作是一个特性包。用对象字面量语法来定义一个变量或者对象,会自动初始化部分属性(也就是说,你定义一个var a = "Hello",那么a本身就会有a.substring这个方法,以及a.length这个属性,以及其它;如果你定义了一个对象,var a = {},那么a就会自动有a.hasOwnProperty及a.constructor等属性和方法。)这些属性和方法都可以被更改,包括其它复杂对象。
"Normal" objects, and functions
A JavaScript object is a mapping between keys and values. Keys are strings and values can be anything. This makes objects a natural fit for hashmaps. However, one has to be careful about the non-standard __proto__ pseudo property. In environment that supports it, '__proto__'
does not allow to manipulate one property with such a name, but the object prototype. In context where it is not necessarily known where the string comes from (like an input field), caution is required: other have been burned by this. In that case, an alternative is to use a proper StringMap abstraction.
Functions are regular objects with the additional capability of being callable.
Arrays
Arrays are regular objects for which there is a particular relationship between integer-key-ed properties and the 'length' property. Additionally, arrays inherit from Array.prototype which provides to them a handful of convenient methods to manipulate arrays like indexOf (searching a value in the array) or push (adding an element to the array), etc. This makes arrays a perfect candidate to represent lists or sets.
Dates
When considering representing dates, the best choice is certainly to use the built-in Date utility
WeakMaps, Maps, Sets
Non-standard. Likely to be standardized as part of ECMAScript 6.
These data structures take object references as keys. A Set represents a set of objects, while WeakMaps and Maps associates a value to an object. The difference between Maps and WeakMaps is that in the former, object keys can be enumerated over. This allows garbage collection optimizations in the latter case.
One could implement Maps and Sets 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 WeakMaps) 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. Maps and WeakMaps make easy to privately bind data to an object.
TypedArrays
Non-standard. Likely to be standardized as part of ECMAScript 6.
See also
文档标签和贡献者
对本页有贡献的人: polucy, _WhiteCusp, Elvis_7, keechi, teoli
最后编辑者: teoli, May 6, 2014 12:59:34 AM