JavaScript data types and data structures

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'utilitzar responseText, 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:

Atributs de les propietats de tipus dada
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:

Atributs de les propietats de tipus accés
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  

Vegeu també

Document Tags and Contributors

 Contributors to this page: enTropy
 Last updated by: enTropy,