Tots els llenguatges de programació tenen estructures de dades definides com a part d'ells mateixos. Aquestes estrcutures, però, són sovint varien d'un llenguatge a un altre. Aquest article pretén llistar totes les estructures de dades que JavaScript té de forma interna, així com quines propietats tenen; aquestes estructures es poden utilitzar per a per a construir altres estrcutures. Es mostraran comparacionis amb altres llenguatges de programació quan sigui possible.
Tipatge dinàmic
JavaScript és un llenguatge de tipatge fluix, o
dinàmic. Això vol dir que no cal declarar el tipus d'una variable abans d'utilitzar-la. El seu tipus es determinarà mentre el programa s'executi. Això també implica que la mateixa variable pot rebre valors que tinguin diferents tipus:
var foo = 42; // foo ara és un Number var foo = "bar"; // foo ara és un String var foo = true; // foo ara és un Boolean
Tipus de dades
L'últim standard ECMAScript defineix set tipus de dades:
Valors primitius
Tots els tipus, a excepció dels objectes, defineixen valors immutables (valors que no es poden canviar). Per exemple, al contrari que C, els Strings són immutables. Ens referim a valors d'aquests tipus com a "valors primitius".
Tipus Booleà
Els booleans representen una entitat lògica i poden tenir un dels dos valors següents: true
, o bé false
.
Tipus Null
El tipus Null té un únic valor: null
. Vegeu null
i Null per a més detalls.
Tipus Undefined
Una variable a la que no se l'ha assignat cap valor té el valor undefined
. Vegeu undefined
i Undefined per a més detalls.
Tipus Number
Segons el standard ECMAScript, només hi ha un tipus que representi nombres: el valor de doble precisió de 64 bits en format binari IEEE 754 (capaç de representar nombres entre -(253 -1) i 253 -1). No hi ha un tipus específic per a representar nombres sencers. A més de ser capaç de representar nombres en coma flotant, el tipus Number disposa de tres valors adicionals simbòlics: +Infinity
, -Infinity
, i NaN
(No un Nombre, de l'anglés Not-A-Number).
Per a comprovar valors més grans o més petits que +/-Infinity
, es poden emprar les constants Number.MAX_VALUE
i Number.MIN_VALUE
i, a partir de l'ECMAScript 6, també es pot comprovar si un nombre en coma flotant de doble precisió està dins el rang mitjançant Number.isSafeInteger()
, així com Number.MAX_SAFE_INTEGER
i Number.MIN_SAFE_INTEGER
. Fora d'aquest rang no és segur utilitzar nombres a JavaScript.
El tipus Number disposa únicament d'un nombre sencer que té dues representacions: 0 s'interpreta com a -0 i +0. ("0" és un alias per a +0). A la pràctica, això no te quasi cap impacte. Per exemple, +0 === -0
evalua a true
. No obstant, aquesta diferència si existeix quan es divideix per zero:
> 42 / +0 Infinity > 42 / -0 -Infinity
Tot i que un nombre sovint només representa el seu valor, JavaScript disposa d'alguns operadors binaris. Aquests operadors es poden emprar per a representar un conjunt de valors Booleans dins un sol nombre utilitzan una màscara de bits. Això es considera una mala pràctica tot i que JavaScript no ofereix cap altra forma per a representar un conjunt de Booleans (com ara un array de Booleans o un objecte amb valors assignats a propietats amb nom). Utilitzar màscares de bits també tendeix a fer el codi més dificil de llegir, entendre i mantindre. Pot ser necesari l'ús d'aquestes tècniques en entorns força limitats, com ara quan es disposa de pocs recursos d'emmagatzematge local o en casos extrems quan cada bit enviat a la xarxa compta. Només hauria de considerar-se l'ús d'aquesta tècnica quan sigui l'últim recurs que es pot emprar per a optimitzar espai.
Tipus String
El tipus String
de JavaScript s'utilitza per a representar dades textuals. Es tracta d'un llistat d'"elements" el valor dels quals és un nombre sencer de 16 bits sense signe. Cada element dins el String ocupa una posició. El primer element té l'índex 0, el segon index 1, etcètera. La llargada d'un String és el nombre d'elements que conté.
A diferència d'altres llenguatges, com ara C, Els strings a JavaScript són immutables. És a dir, quan un string s'ha creat, no és possible modificar-lo. En comptes d'això, si que és possible crear un nou string basat en un string ja existent mitjançant una operació sobre l'original. Per exemple:
- Un substring de l'original via escollint lletres individuals o bé mitjançant
String.substr()
. - Una concatenació de dos strings mitjançant l'operador de concatenació (
+
) o béString.concat()
.
Alerta amb abusar dels strings!
Pot ser temptador utilitzar strings per a representar dades complexes. Fer-ho comporta beneficis a curt termini:
- Resulta senzill construir strings complexos mitjançant la concatenació.
- Els strings són fàcils de depurar (el que es veu imprés sempre és el que el string conté).
- Els strings són el denominador comú de moltes APIs (camps d'entrada, valors emmagatzemats de forma local, respostes
XMLHttpRequest
a l'utilitzarresponseText
, etc.) i pot resultar temptador utilitzar només strings.
Amb les convencions adequades, és possible representar estructures de dades dins un string. Això no vol dir que fer-ho sigui una bona idea. Per exemple, amb un separador, seria possible emular una llista (tot i que un array de JavaScript seria més adient). Malauradament, quan s'utilitzi el separador en un dels elements de la "llista", la llista esdevendrà errònia. Una solució seria escollir un caràcter d'escapament, etcètera. Tot això requereix de convencions i crea un problema de manteniment innecesari.
Utilitzeu strings només per a dades textuals. Quan representin dades complexes, interpreteu els strings i utilitzeu l'abstracció adequada.
Tipus Symbol
El tipus Symbol és nou a JavaScript, introduït a l'ECMAScript Edició 6. Un Symbol és un valor primitiu únic i immutable i pot ser utilitzat com a clau d'una propietat d'un objecte (vegeu més abaix). En alguns llenguatges de programació, als símbols s'els anomena àtoms. També guarden similituts a les enumeracions (enum) de C. Per a més detalls vegeu Symbol i l'objecte embolcallador Symbol
a JavaScript.
Objectes
En l'àmbit de la informàtica, un objecte és un valor en memòria que possiblement és referenciat per un identificador.
Propietats
A JavaScript es poden entendre els objectes com una col·lecció de propietats. Amb la sintaxi literal d'objectes, es pot inicialitzar un conjunt de propietats limitat; més tard es poden afegir propietats o bé esborrar-ne. Els valors de les propietats poden ser de qualsevol tipus, incloent altres objectes, el que comporta poder construir estructures de dades complexes. Les propietats s'identifiquen mitjançant valors clau. Una clau és o bé un valor de tipus String o Symbol.
Hi ha dos tipus de propietats d'objectes, les quals tenen diferents atributs: Les propietats de tipus dada i les propietats de tipus accés.
Propietats de tipus dada
Associa una clau a un valor i disposa dels següents atributs:
Atribut | Tipus | Descripció | Valor per defecte |
---|---|---|---|
[[Value]] | Qualsevol tipus | El valor obtingut mitjançant un accés de tipus get a la propietat. | undefined |
[[Writable]] | Boolean | Si val false , el [[Value]] de la propietat no es pot canviar. |
false |
[[Enumerable]] | Boolean | Si val true , la propietat apareixerà al recòrrer l'objecte pare amb un bucle for...in. |
false |
[[Configurable]] | Boolean | Si val false , la propietat no pot ser esborrada i no es pot modificar cap atribut a excepció de [[Value]] i [[Writable]]. |
false |
Propietats de tipus accés
Associen una clau amb una o dues funccións d'accés (get i set) per a obtindre o bé emmagatzemar un valor, i tenen els atributs següents:
Atribut | Tipus | Descripció | Valor per defecte |
---|---|---|---|
[[Get]] | Objecte de tipus Function o bé undefined | Es crida la funció amb un llistat d'arguments buit i retorna el valor de la propietat. S'executa quan s'accedeix al valor de la propietat. Vegeu també get . |
undefined |
[[Set]] | Objecte de tipus Function o bé undefined | Es crida la funció amb un argument, que conté el valor a assignar a la propietat. S'executa quan es vol canviar el valor de la propietat. See also set . |
undefined |
[[Enumerable]] | Boolean | Si val true , la propietat apareixerà al recòrrer l'objecte pare amb un bucle for...in. |
false |
[[Configurable]] | Boolean | Si val false , no es pot esborrar la propietat i no es pot convertir a una propietat de tipus dada. |
false |
Objectes "normals" i functions
A JavaScript, un objecte és un mapa que associa claus amb valors. Les claus sempre són de tipus String mentre que els valors poden ser de qualsevol tipus. Això fa que els objectes es puguin utilitzar de forma intuitiva com a hashmaps.
Les funcions són objectes normals i correncts amb la característica adicional que poden ser cridats.
Dates
A l'hora de representar dates la millor opció és utilitzar l'objecte Date
que JavaScript incorpora per defecte.
Col·leccions indexades: Arrays i Arrays amb tipus
Els Arrays són objectes normals i corrents en els que hi ha una relació específica entre les propietats, que utilitzen nombres sencers com a claus, i la propietat 'length'. A més, els array hereten de Array.prototype
, el qual els proporciona un conjunt de mètodes molt útils per a manipular arrays. Per exemple, indexOf
(cerca un valor dins l'array) o bé push
(afegeix un element a l'array), etcètera. Això fa que els Arrays siguin el candidat ideal per a representar llistes i sets.
Els Arrays amb tipus s'han incorporat a JavaScript recentment amb el standard ECMAScript Edició 6 i ofereixen una forma de treballar sobre buffers de dades binàries com si es tractessin d'arrays. La taula següent mostra el tipus de dades equivalent a C:
TypedArray objects
Type | Size in bytes | Description | Web IDL type | Equivalent C type |
Int8Array |
1 | 8-bit two's complement signed integer | byte |
int8_t |
Uint8Array |
1 | 8-bit unsigned integer | octet |
uint8_t |
Uint8ClampedArray |
1 | 8-bit unsigned integer (clamped) | octet |
uint8_t |
Int16Array |
2 | 16-bit two's complement signed integer | short |
int16_t |
Uint16Array |
2 | 16-bit unsigned integer | unsigned short |
uint16_t |
Int32Array |
4 | 32-bit two's complement signed integer | long |
int32_t |
Uint32Array |
4 | 32-bit unsigned integer | unsigned long |
uint32_t |
Float32Array |
4 | 32-bit IEEE floating point number | unrestricted float |
float |
Float64Array |
8 | 64-bit IEEE floating point number | unrestricted double |
double |
Col·leccions amb claus: Maps, Sets, WeakMaps, WeakSets
Aquestes estructures de dades utilitzen referències a objectes com a claus i estan disponibles a partir de l'ECMAScript Edició 6. Set
i WeakSet
representen un conjunt d'objectes, mentre que Map
i WeakMap
associen valors a objectes. La diferència entre Maps i WeakMaps és que als Maps els objectes utilitzats com a clau es poden enumerar mentre que als WeakMaps no. Això permet optimitzar l'alliberament de memòria si es fan anar WeakMaps.
Els Maps i Sets es podrien implementar utilitzant solament ECMAScript 5 però, com que els objectes no es poden comparar (en el sentit de poder considerar un objecte menor que un altre, per exemple), el rendiment a l'hora de cercar seria linear per força. Les implementacions d'aquestes col·leccions (incloent WeakMaps) permeten un rendiment superior, sent aproximadament entre logarítmic i constant.
Normalment, a l'hora de vincular dades a un node del DOM, s'assignen propietats directament a l'objecte o s'utilitzen atributs del tipus data-*
. Aquesta aproximació té l'inconvenient d'exposar aquestes dades a tots els scripts pertanyents al mateix context. Els Maps i els WeakMaps són una solució que permet vincular dades a objectes de forma privada.
Dades estructurades: JSON
JSON (JavaScript Object Notation) és un format lleuger per a l'intercanvi de dades, derivat de JavaScript però utilitzat per molts llenguatges de programació. JSON construeix estructures de dades universals. Vegeu JSON i JSON
per a més detalls.
Altres objectes de la llibreria standard
JavaScript disposa d'una llibreria standard d'objectes. Feu un cop d'ull a la referència per a descobrir més objectes.
Determinar el tipus utilitzant l'operador typeof
L'operador typeof
pot ajudar-vos a esbrinar el tipus d'una variable. Llegiu la pàgina de referència per a més detalls i casos especials.
Especificacions
Especificació | Estat | Comentaris |
---|---|---|
ECMAScript 1st Edition (ECMA-262) | Standard | Definició inicial. |
ECMAScript 5.1 (ECMA-262) The definition of 'Types' in that specification. |
Standard | |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'ECMAScript Data Types and Values' in that specification. |
Standard |