简体   繁体   English

字符串相同如何在JavaScript中工作?

[英]How does string equality work in JavaScript?

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: 例如, http//www.w3schools.com/jsref/jsref_obj_string.asp声明:

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? 当然,无论如何都没有人调用new String() ,但它是否因为new String()被处理为一个对象而不是一个字符串而失败了呢?

And of course W3Schools is not the most trusted source but I would have expected all of the above alerts to say true. 当然,W3Schools并不是最值得信赖的来源,但我希望所有上述提醒都能说出来。

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. “令人惊讶的结果”来自Javascript处理对象的相等性,以及字符串文字和String对象之间出现的混淆。 From the Mozilla reference guide for the == operator: 来自==运算符的Mozilla 参考指南

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. 如果两个操作数的类型不同,则JavaScript转换操作数,然后应用严格比较。 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 . 如果两个操作数都是对象,则JavaScript比较内部引用,当操作数引用内存中的同一对象时,这些内部引用相等

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

String literals, which are primitive value types, are different from new String objects, which are entities with distinct references wrapping those values. 字符串文字是原始值类型,与新的String对象不同,后者是包含这些值的不同引用的实体。 See Predefined Core Objects in Mozilla's JavaScript docs for details. 有关详细信息,请参阅Mozilla的JavaScript文档中的预定义核心对象

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. 所以你的对比是对文字和对象的处理方式不同,只是因为一个比较它们的值而另一个比较引用。

You are correct that in your example case you are comparing 2 different object references. 您是正确的,在您的示例中,您正在比较2个不同的对象引用。 Within the language specification you'll find this algorithm. 在语言规范中,您将找到此算法。 The portion you are looking for is section 1 f. 你要找的部分是第1节。

11.9.3 The Abstract Equality Comparison Algorithm 11.9.3抽象等式比较算法

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. 还要注意步骤8和9,这使得处理String对象更加清晰。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM