2011-09-01 17 views
13

Hay un montón de tutoriales para == y === así que por favor no me guiará a un tutorial básico, mi pregunta es un poco más específico:¿Cómo funciona la igualdad de cadenas en JavaScript?

Por ejemplo http://www.w3schools.com/jsref/jsref_obj_string.asp establece que:

Sintaxis:

var txt = new String("string"); 

// or more simply: 
var txt = "string"; 

Bueno, pero ¿qué tal esto?

alert(new String("a") == new String("a")); // false 
alert("a" == "a"); // true 

var a = new String("a"); 
var b = new String("a"); 
alert(a == b); // false 

var c = "a"; 
var d = "a"; 
alert(c == d); // true 

alert(c === d); // true 
alert (a === c); // false 

Por supuesto, nadie llama new String() todos modos, pero es algo acerca de la igualdad de fallar debido new String() se trata como un objeto no como una cadena?

Y, por supuesto, W3Schools no es la fuente más confiable, pero esperaba que todas las alertas anteriores dijeran verdadero.

Explique.

+3

Una mejor referencia es https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String –

+0

Este comportamiento ya se ha explicado, pero una pregunta de seguimiento podría ser "¿Por qué alguna vez uso 'new String()'? " – nnnnnn

+1

solo un pequeño comentario: http://w3fools.com/ – RoelF

Respuesta

12

Los "resultados sorprendentes" provienen de la forma en que JavaScript maneja la igualdad para Objetos, más la confusión que surge entre los literales de cadena y los objetos de Cadena. Desde el Mozilla reference guide para el operador ==:

Si los dos operandos no son del mismo tipo, JavaScript convierte los operandos continuación, se aplica comparación estricta. Si cualquiera de los operandos es un número o un booleano, los operandos se convierten en números si es posible; else si cualquier operando es una cadena, el otro operando se convierte en una cadena si es posible. Si ambos operandos son objetos, entonces JavaScript compara las referencias internas que son iguales cuando los operandos se refieren a el mismo objeto en la memoria.

Puede experimentar el mismo comportamiento con los números:

new Number(5) == new Number(5) // false 

y aclarar su mente por:

typeof "string" // string 
typeof new String("string") // object 
+0

¡Respuesta bonita, clara y completa! ¡Gracias! –

+0

Gracias, esto es lo que deseaba encontrar. – SoonDead

4

Los literales de cadena, que son tipos de valores primitivos, son diferentes de los nuevos objetos String, que son entidades con distintas referencias que envuelven esos valores. Consulte Predefined Core Objects en los documentos de JavaScript de Mozilla para obtener más información.

Así que tienes razón en que la comparación se maneja de manera diferente para los literales y para los objetos, simplemente porque uno compara sus valores mientras que el otro compara las referencias.

3

Tiene razón en que en su caso de ejemplo que está comparando 2 referencias a objetos diferentes . Dentro de la especificación del lenguaje, encontrarás este algoritmo. La parte que está buscando es la sección 1 f.

11.9.3 El resumen Igualdad Comparación Algoritmo

 
11.9.3 The Abstract Equality Comparison Algorithm 

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as 
follows: 

1. If Type(x) is the same as Type(y), then 
    a. If Type(x) is Undefined, return true. 
    b. If Type(x) is Null, return true. 
    c. If Type(x) is Number, then 
     i. If x is NaN, return false. 
     ii. If y is NaN, return false. 
     iii. If x is the same Number value as y, return true. 
     iv. If x is +0 and y is -0, return true. 
     v. If x is -0 and y is +0, return true. 
     vi. Return false. 
    d. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same 
     length and same characters in corresponding positions). Otherwise, return false. 
    e. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false. 
    f. Return true if x and y refer to the same object. Otherwise, return false. 
2. If x is null and y is undefined, return true. 
3. If x is undefined and y is null, return true. 
4. If Type(x) is Number and Type(y) is String, 
return the result of the comparison x == ToNumber(y). 
5. If Type(x) is String and Type(y) is Number, 
return the result of the comparison ToNumber(x) == y. 
6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y. 
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y). 
8. If Type(x) is either String or Number and Type(y) is Object, 
return the result of the comparison x == ToPrimitive(y). 
9. If Type(x) is Object and Type(y) is either String or Number, 
return the result of the comparison ToPrimitive(x) == y. 
10. Return false. 

también tomar nota de que los pasos 8 y 9 que hace frente a objetos string un poco más limpia.

alert(new String("a") == "a"); // true 
alert("a" == new String("a")); // true 
+0

Gracias por esto también, he aceptado otra respuesta, pero esto fue igual de educativo. – SoonDead

Cuestiones relacionadas