2011-09-01 12 views
13

Istnieje wiele tutoriali do == i === więc proszę nie prowadź mnie do podstawowego samouczka, moje pytanie jest nieco bardziej szczegółowe:Jak działa równość łańcuchów w JavaScript?

Na przykład http://www.w3schools.com/jsref/jsref_obj_string.asp stwierdza, że:

Składnia:

var txt = new String("string"); 

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

Dobrze, ale co z tym?

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 

oczywiście nikt nie zwraca new String() tak, ale jest to coś, o równości upadającego ponieważ new String() jest traktowane jako nie jako obiektu ciąg?

I oczywiście W3Schools nie jest najbardziej zaufanym źródłem, ale oczekiwałbym, że wszystkie powyższe alarmy będą prawdziwe.

Proszę wyjaśnić.

+3

Znacznie lepiej odniesienia jest https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String –

+0

Takie zachowanie został wyjaśniony, ale kontynuacją pytanie może być „Dlaczego chcesz kiedykolwiek używasz 'new String()'? " – nnnnnn

+1

tylko mała uwaga: http://w3fools.com/ – RoelF

Odpowiedz

12

"Zaskakujące wyniki" pochodzą ze sposobu, w jaki Javascript obsługuje równość obiektów, plus zamieszanie, jakie powstaje między literałami ciągów a obiektami String. Z Mozilla reference guide dla operatora ==:

Jeżeli oba argumenty nie są tego samego typu, JavaScript konwertuje argumentów następnie stosuje ścisłe porównanie. Jeśli jeden z operandów to liczba lub boolean, operandy są konwertowane na liczby, jeśli to możliwe; else jeśli jeden z argumentów jest ciągiem, drugi operand jest konwertowany na ciąg znaków , jeśli to możliwe. Jeśli oba operandy są obiektami, to JavaScript porównuje wewnętrzne odniesienia, które są równe, gdy operandy odnoszą się do tego samego obiektu w pamięci.

może wystąpić ten sam problem z numerami:

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

i wyjaśnić swój umysł przez:

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

Ładna, przejrzysta i wyczerpująca odpowiedź! Dzięki! –

+0

Dzięki, to jest to, co chciałem znaleźć. – SoonDead

4

Literały łańcuchów, które są prymitywnymi typami wartości, różnią się od nowych obiektów String, które są obiektami z różnymi odniesieniami zawijającymi te wartości. Zobacz: Predefined Core Objects w dokumentach JavaScript Mozilli, aby uzyskać szczegółowe informacje.

Masz rację, że porównanie jest traktowane inaczej w przypadku literałów i obiektów, ponieważ porównuje się ich wartości, podczas gdy inne porównują odniesienia.

3

Masz rację, że w przykładowym przypadku porównywania 2 różnych odwołań do obiektów . W specyfikacji językowej znajdziesz ten algorytm. Część, której szukasz, to sekcja 1 f.

11.9.3 Abstrakcyjny Równość Algorytm Porównanie

 
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. 

wziąć również zauważyć, że kroki 8 i 9, które sprawia, że ​​do czynienia z ciągiem obiektów czystsze bit.

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

Dziękuję za to również, że przyjąłem inną odpowiedź, ale to było tak samo edukacyjne. – SoonDead