2012-06-08 1 views
97

que iba a comenzar a utilizar === (iguales triples, comparación estricta) todo el tiempo al comparar los valores de cadena, pero ahora me parece que¿Por qué ("foo" === new String ("foo")) se evalúa como falso en JavaScript?

"foo" === new String("foo") 

es falso, y lo mismo con esto:

var f = "foo", g = new String("foo"); 
f === g; // false 

por supuesto:

f == g; // true 

lo tanto, es recomendable utilizar siempre == para la comparación de cadenas, o siempre convertir las variables en cadenas antes de la comparación?

+4

Tal vez porque 'foo' es la cadena pura y' nueva cadena ("foo") 'es la cadena de objetos –

+0

Antecedentes: http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript –

+6

Se recomienda no crear cadenas con 'new String' (completamente inútil) en lugar de usando '==' – Esailija

Respuesta

124

"foo" es una cadena primitiva. (este concepto no existe en C# o Java)

new String("foo") es un objeto de cadena en caja.

El operador ===behaves differently on primitives and objects.
Al comparar primitivas (del mismo tipo), === devolverá verdadero si ambos tienen el mismo valor.

Al comparar objetos, === devolverá verdadero solo si se refieren al mismo objeto (comparando por referencia). Por lo tanto, new String("a") !== new String("a").

En su caso, === devuelve falso porque los operandos son de tipos diferentes (uno es un primitivo y el otro es un objeto).


Los primitivos no son objetos en absoluto.
El operador typeof no devolverá "object" para las primitivas.

Cuando intente acceder a una propiedad de una primitiva (usándola como un objeto), el idioma de Javascript lo encuadrará en un objeto, creando un nuevo objeto cada vez. Esto se describe en el specification.

Esto es por lo que no se puede poner en primitivas propiedades:

var x = "a"; 
x.property = 2; 
alert(x.property) //undefined 

Cada vez que escriba x.property, se crea un objeto diferente caja String.

+32

+1 'typeof" foo "; // "string" ',' typeof new String ("foo"); // "object" ' – Sampson

+1

Interesante, pensé que las cuerdas eran objetos en JS. – ddlshack

+0

@ddlshack: todo puede ser un objeto incluso en cadena si lo creas en su instancia. – Sarfraz

4

foo es la cadena pura y new String("foo") es la cadena de objetos

34

Usando ===,

  • un objeto nunca es igual a nada más que otra referencia a sí mismo.

  • una primitiva es igual en comparación con otra primitiva si su tipo y valor son los mismos.

+3

'new String (" foo ") === new String (" foo ")' is 'false' :-P –

+11

@Rocket: Exactamente mi punto. –

+5

@Rocket: debería ser porque son dos referencias diferentes ... –

10

La palabra new es un criminal aquí ( como de costumbre, debo decir) ...

Cuando se utiliza new, que expresan explícitamente su deseo de trabajar con objeto. Podría ser sorprendente para usted, pero esto:

var x = new String('foo'); 
var y = new String('foo'); 
x === y; 

... le dará un poderoso false. Es simple: comparados no son los interiores de los objetos, sino las referencias de los objetos. Y ellos, por supuesto, no son iguales, ya que se crearon dos objetos diferentes.

Lo que es probable que desee utilizar es la conversión :

var x = String('foo'); 
var y = String('foo'); 
x === y; 

... y que le dará, como se esperaba, true como resultado, por lo que puede alegrarse y prosperar con su equivalente foos siempre.)

+2

pregunta rápida sobre el uso de esto. ¿Estás llamando a String (un constructor?) Sin la palabra clave 'nueva'. ¿Esto no significa que va a contaminar el alcance con cualquier propiedad asignada dentro del constructor String? ¿O eso no sucede porque el constructor es un código nativo? En otras palabras, supongamos que la función String contiene "this.a = 1;" - eso significa que su función/objeto ahora tendría una propiedad a = 1. –

+0

Supongo (pero no puedo decirlo con certeza) que cada una de las funciones del 'constructor del boxeo' comprueba primero su contexto, y si no es 'nueva' (es decir, un objeto prototipo), cambia al método de conversión de inmediato. En el caso de String, ese sería el método 'toString()', por ejemplo. – raina77ow

2

Desde el Node.js REPL ("nodo" en la línea de comandos si está instalado):

> "foo" === (new String("foo")).valueOf() 
true 
> "foo" === new String("foo") 
false 
> typeof("foo") 
'string' 
> typeof(new String("foo")) 
'object' 
> typeof((new String("foo")).valueOf()) 
'string'
Cuestiones relacionadas