2012-03-13 18 views
18

Los objetos Javascript se pueden usar como mapas. La siguiente todo es código válido:¿Es nulo un nombre de propiedad javascript válido?

var x = {}; 
x.a = 1; 
x['b'] = 2; // the same as x.b = 2; 
x[3] = 3; // x.3 won't work, but this syntax works fine. Also, x[3] == x['3']. 
x['What, this works too?!?!?'] = 'Yup, it does!'; 

Pero hoy he probado otro caso que ... parece funcionar, pero plantea algunas banderas de advertencia en mi cabeza porque se ve mal ...:

x[null] = 42; 

Ahora, sería genial si funcionara como se esperaba (no tendré que volver a escribir un montón de código), pero ¿puedo confiar en ello? O tal vez esto es solo un comportamiento indocumentado que solo sucede para funcionar en todos los navegadores modernos, pero ¿podría dejar de funcionar en la próxima versión de Google Chrome?

+1

El argumento de indexación se convierte en una cadena antes de realizar cualquier operación. Pruebe 'console.log (x [" null "])' después de su última tarea. Usted notó que cuando se trata del subíndice '3'. –

+1

También es divertido: 'x [x] = 1', que técnicamente está indexado como' x ['[object object]'] 'y el mismo valor que' x [{}] '. Y si odias a otras personas: 'x [x [x]] = 2'. – Deestan

Respuesta

17

Cualquier cosa entre los soportes de propiedad se convierte en una cadena. null se convierte en "null", que es una propiedad válida.

+0

¡Por George, tienes razón! ¡Genial, funciona para mí! :) –

+1

@ Vilx- PS. 'var d = {}; d [{}] = 1; JSON.stringify (d)' muestra '{" [object Object] ":" "}' y 'var x = {}; x [{toString: function() {return 123}}] = 1; Object.keys (x) 'contiene' 123'. –

+0

También, vea http://stackoverflow.com/a/10362142 para una discusión en profundidad sobre por qué null tiene una representación de cadena. – bebbi

0
x['null'] = 42; 

No lo recomendaría, sin embargo, para evitar confusiones.

Los nombres de las propiedades son cadenas. Cada cadena funcionará, incluso aquellas que representan identificadores reservados.

Todo lo que no es una cadena se convierte en una cadena (llamando al método del objeto toString()):

a = ['FOO']; // an array 
o = {};  // an object 
o[a] = 'foo'; // using a as the property name 

// o now is: 
{ 
    FOO: 'foo' 
} 
+0

En mi caso, los índices son numéricos, excepto por el índice especial "nulo". No creo que cause confusión. –

+0

Bueno, huele, como redefinir 'undefined'. Los índices numéricos también se convierten en picaduras. – Tomalak

+0

¿Hm? No estoy redefiniendo nada. Es como ... hay un montón de objetos de datos y necesito agruparlos por una de sus propiedades (esa propiedad en realidad es una identificación numérica en la base de datos). Hoy me encontré con la situación en la que también necesitaba incorporar datos de otra fuente de datos, pero los objetos de datos que provienen de esa fuente no incluyen una identificación para esta propiedad. No pertenecen a ninguno de los grupos que hacen los artículos originales, sino que ... pertenecen a todos ellos, más o menos. Entonces necesito un valor especial para marcar esos objetos, y null parece un buen ajuste. –

-1

no puedo dejar comentarios así que creé una respuesta ...

Mientras Rob W es correcta su respuesta es un poco engañoso. El elemento entre corchetes se convierte en una cadena usando ToString(). Por lo tanto, un [nula] Sólo es igual a una [ 'nulo'] porque ToString (nulo) == 'nulo'

Tomemos por ejemplo

var a = 1; 
var x = {} 

x[a] = 20; 
x['1'] = 30; -- this is exactly the same as the previous line and now x[a] == 30 
1

Es ECMAScript válida 5, pero puede tener problemas en algunas versiones de Internet Explorer.

todo esto está bien:

x = {}; 
x[null] = 42; 
x[null]; 
// 42 

x = {"null": 42}; 
x[null]; 
// 42 

Sin embargo, IE8 no acepta lo siguiente con palabras reservadas como null:

x.null 
// Error: Expected identifier 

x = {null: 42} 
// Expected identifier, string or number 

(ambos el trabajo anterior en Chrome, incluso con "use strict" activado.)

0

Si su entorno admite ES6 y necesita poder almacenar un valor para null así como cualquier cadena arbitraria, entonces puede usar un Map.

const a = new Map(); 

a.set(null, 'foo') 
a.set('null', 'bar') 

// Map { null => 'foo', 'null' => 'bar' } 
Cuestiones relacionadas