How does string equality work in JavaScript?

javascript equals string
javascript string comparison not working
how to compare two strings in javascript if condition
javascript string not equal
javascript vs
how to compare two strings character by character in javascript
javascript comparison operators
javascript object equality

There are plenty of tutorials for == and === so please don't guide me to a basic tutorial, my question is a bit more specific:

For example http://www.w3schools.com/jsref/jsref_obj_string.asp states that:

Syntax:

var txt = new String("string");

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

Good, but what about this?

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

Of course nobody calls new String() anyway, but is it something about the equality failing because new String() is handled as an object not as a string?

And of course W3Schools is not the most trusted source but I would have expected all of the above alerts to say true.

Please explain.

The "surprising results" come from the way Javascript handles equality for Objects, plus the confusion that arises between string literals and String objects. From the Mozilla reference guide for the == operator:

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the other operand is converted to a string if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.

You can experience the same behavior with numbers:

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

And clarify your mind by:

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

Comparison operators, There are four equality algorithms in ES2015: one is -0 . var num = 0; var obj = new String('0'); var str = '0'; console.log(num === num); // true  In the above table, ToNumber(A) attempts to convert its argument to a number before comparison. Its behavior is equivalent to +A (the unary + operator).ToPrimitive(A) attempts to convert its object argument to a primitive value, by attempting to invoke varying sequences of A.toString and A.valueOf methods on A.

String literals, which are primitive value types, are different from new String objects, which are entities with distinct references wrapping those values. See Predefined Core Objects in Mozilla's JavaScript docs for details.

So you're right in that comparison is handled differently for literals and for objects, simply because one compares their values while the other compares references.

Equality comparisons and sameness, Compares two strings to see if they are the same. This method is necessary because it's not possible to compare strings using the equality operator (==). Returns  Examples. The following example creates a string array that consists of an uppercase "I", a lowercase "i", and a dotless "ı". It then calls the Equals(String, StringComparison) method to compare them by using each possible StringComparison enumeration value.

You are correct that in your example case you are comparing 2 different object references. Within the language specification you'll find this algorithm. The portion you are looking for is section 1 f.

11.9.3 The Abstract Equality Comparison Algorithm

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. 

Also take notice that steps 8 and 9 which makes dealing with String objects a bit cleaner.

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

Comparisons, Primitive types in JavaScript are considered numbers, strings, booleans, It is worth mentioning that NaN in identity (and in equality) operator  JavaScript has both strict and type–converting comparisons. A strict comparison (e.g., ===) is only true if the operands are of the same type and the contents match. The more commonly-used abstract comparison (e.g. ==) converts the operands to the same type before making the comparison. For relational abstract comparisons (e.g., =), the operands are first converted to primitives, then to the

equals() | reference, The question is to compare 2 JavaScript strings optimally. To do so, Here are a few of the most used techniques discussed. This method discussed below is  The reason is that an equality check == and comparisons > < >= <= work differently. That’s why (3) null >= 0 is true and (1) null > 0 is false. On the other hand, the equality check == for undefined and null is defined such that, without any conversions, they equal each other and don’t equal anything else.

The Legend of JavaScript Equality Operator, Comparison operators are used in logical statements to determine equality or When comparing a string with a number, JavaScript will convert the string to a  Since we used the === operator on this occasion, and because this operator does not do any type conversion, we see that the string value "3" and the number 3 are not the same after all. When in doubt, a relatively safe choice is simply to use the identity operator (===) as a matter of habit.

Optimum way to compare strings in JavaScript, You know there are two different equality comparison operators in JavaScript: And the same logic works for inequality comparison operators !== and != as well When comparing the string "0" and the number 0 the result is false as expected​  String Methods and Properties Primitive values, like "John Doe", cannot have properties or methods (because they are not objects). But with JavaScript, methods and properties are also available to primitive values, because JavaScript treats primitive values as objects when executing methods and properties.

Comments
  • A much better reference is developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
  • This behaviour has now been explained, but a follow-up question might be "Why would you ever use new String()?"
  • just a small remark: w3fools.com
  • Just don't use new String(). I can't think of a single use case for it.
  • Thanks, this is what I wished to find.
  • Thanks for this also, I have accepted an other answer but this was just as educational.