2011-05-28 13 views

Respuesta

10

la matriz es irrelevante - usted está tratando de establecer una propiedad en un primitive:

Un dato que no es un objetoy hace no tiene ningún métodos. JavaScript tiene 5 primitivos tipos de datos:cadena, número, booleano, nula, indefinido. Con la excepción de null e indefinido, todos los valores de las primitivas tienen el objeto equivalentes que envuelve alrededor de los valores primitivos , p. un objeto String se envuelve alrededor de una primitiva de cadena. Todas las primitivas son inmutables.

Si es absolutamente necesario utilizar una propiedad para llevar esta información adicional en torno a una cadena, una alternativa sería utilizar el objeto equivalente:

>>> var array = [new String('a'), new String('b'), new String('c')]; 
>>> array[0].property 
undefined 
>>> array[0].property = 'value' 
"value" 
>>> array[0].property 
"value" 

Gotcha potencial a tener en cuenta si lo hace esto y más tarde necesidad de detectar que el valor es una cadena:

>>> var a = ['s', new String('s')]; 
>>> a.map(function(s) { return typeof s; }); 
["string", "object"] 
>>> a.map(function(s) { return s instanceof String }); 
[false, true] 
>>> a.map(function(s) { return Object.prototype.toString.call(s) == '[object String]' }); 
[true, true] 
+1

otro gotcha: '[new String ('a')]. IndexOf ('a') === -1' – OrangeDog

2

array[0] es una cadena, es decir, 'a' que establece en la primera línea y en cadenas de JavaScript no puede tener propiedades adicionales.

Si desea utilizar las propiedades que tienen que usar un objeto, por ejemplo un simple "vacío" objeto: new Object() o corto {}:

var array = [{}]; 
array[0].property = 'value'; 

alert(array[0].property); 
alert(array[0].property = 'value'); 
alert(array[0].property); 
+0

Mierda. Nunca lo supe. Parece que los números tampoco pueden tener propiedades adicionales. ¡Gracias! – ClosureCowboy

+0

¿Alguna razón para los votos hacia abajo? – RoToRa

+0

Me preguntaba lo mismo. Usted tiene un voto favorable de mi parte. – ClosureCowboy

1

usted está tratando de hacer 'a'.property = 'something'.

No conozco ningún lenguaje que le permita asignar una propiedad de una cadena;

que sería como hacer 12.property = 'something'.

+1

Puede, sin embargo, asignar una propiedad al * prototipo * de una cadena. Puede escribir 'String.prototype.property = 'something'', que hará que todas las cadenas tengan una propiedad' property' con el valor de 'something'. Incluyendo ''a'.property'. – rid

+0

@rdineiu Ah sí, lo uso todo el tiempo para hacer ''string'.contains (' substring ')'. Sin embargo, parecía que quería hacer ''a'.prop = 1; 'b'.prop = 2; ... '; al menos eso estaba implícito en el código. Sin embargo, es desafortunado que, debido a problemas de lenguaje y biblioteca, la modificación de Array.prototype y Object.prototype sea peligrosa, por lo que esas funciones obtienen menos uso de lo que deberían. – ninjagecko

3

Sus elementos de la matriz son literales de cadena . JavaScript hace que parezca que los literales de cadena son objetos y tienen propiedades, pero lo que realmente está sucediendo cuando lo hace array[0].property es que JavaScript está creando un objeto temporal para su cadena y asignando la propiedad a eso.

Es por eso que la alerta media funciona correctamente y las otras no.Si declaró su matriz como:

var array = [new String('a'), new String('b'), new String('c')]; 

las tres funcionarían.

2

Esto es debido a una peculiaridad (o restricción de rendimiento) en JavaScript - los primitivos tipos string, boolean y numberson inmutables y cualquier asignación de propiedad será simplemente "desaparecer" (los tipos primitivos de un solo habitante undefined y null arrojarán una excepción en la asignación de propiedades intentada). Esto se debe a que estos valores primitivos son no objetos reales (los hace mucho más livianos durante el tiempo de ejecución).

Sin embargo, para cada uno de los tipos primitivos hay un tipo envoltura: String, Boolean, y Number, respectivamente. Los tipos de envoltura son objetos reales y pueden tener propiedades personalizadas asignadas.

Mientras yo no haría esto, esto va a funcionar (suena como un "diseño repulsivo"):

var s = new String("foo"); 
s.bar = "hello" 
alert(s.bar) 

Sin embargo, hay una serie de rarezas que esto introduce - typeof "" es "cadena" mientras typeof s es "objeto" *, y "" instanceof String es falso, mientras que s instanceof String es verdadero. Además, new Boolean(false) es un valor de verdad.

Happy coding.


* Esto romperá una serie de biblioteca de Noddy que hacer typeof x === "string"

0

En js cadenas y tipos simples almacenados/devueltos por valor, no por referencia.

Si en su matriz tiene algún objeto, entonces funcionará.

+0

Si bien el problema tiene que ver con las propiedades en los valores de' cadena', no hay ningún "valor" frente a . distinción "referencia" en JavaScript. –

+0

@pst, todas excepto las primitivas son siempre por referencia en JS. Primitivos - por valor. – gaRex

+1

Todos los valores en JavaScript son "por valor" o "solo ellos mismos"; es decir, el valor de un objeto es en sí mismo - * no hay referencia *. (Las implementaciones pueden usar referencias * internamente *; este detalle no se filtra). Todos los valores primitivos son * completamente * inmutables.* Java * introduce la distinción de "tipos de referencia"; JavaScript no tiene esa distinción y la semántica de las llamadas se describe por completo mediante [Llamada por intercambio de objetos] (http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) sin la necesidad de introducir "referencias" de diferentes idiomas. –

Cuestiones relacionadas