JavaScript字符串比较 == 有时会失败

38

以下代码如何有时会评估为false?

(transport.responseText == '1' || 
 transport.responseText == 'CARD_VALID')

我的JavaScript代码:

if (transport.responseText == '1' || 
    transport.responseText == 'CARD_VALID') {
    // do something.
}
else if (transport.responseText == 'CARD_INVALID' || 
             transport.responseText == 'INVALID_CHECKSUM') {
    // do something else....
}
else {
    new Ajax.Request('/report_error.php?responseText='+transport.responseText);
    // report error to user
}

当两个字符串完全相同但 JavaScript 字符串比较操作符 == 返回 false 时,可能会发生什么?


1
JavaScript的等号操作符==没有错误,它不会失败。只要左右两边的字符串内容相同,它就会返回true。如果返回false,则可能是以下原因之一:1.这些字符串不同;2.其中一个字符串前后有空格;3.其中一个字符串中有隐藏的控制字符或Unicode字符。 - Eric Leschinski
我通过添加.trim()解决了问题,但在比较其他值时也可以使用.toString() - nodws
11个回答

69

在JavaScript中,使用双等号是比较字符串的适当方式,如果返回false,则可能一个字符串左侧和/或右侧存在空格。

在字符串的末尾加上.trim(),我的比较应该可以正常工作:

var panel = response.substr(0, response.indexOf("<")).trim();
if(panel == "combo"){
    //do something
}

2
哇,这是一个很老的问题,但感谢您的回答。我可能尝试过了,但谁知道...那已经是三年前的事了。对于任何遇到此问题的人:请尝试这个方法。如果有效,请在此处评论,我会将此答案标记为正确! - chaimp
1
是的。这是一个好提示。我也在比较“完全相同”的字符串(甚至连可见的空白字符也一样),但它们没有匹配,因为其中一个字符串有一个换行符或回车符(或其他什么),当我试图找出问题时,它没有显示出来。 - Ярослав Рахматуллин
4
应该使用等值比较符号:"if (panel === "combo")"。 - retrodrone
我有相反的问题,两个极不相同的字符串返回相等,这让我感到非常困惑。 - Joe Yahchouchi
2
你救了我的心智 - 通过 .length 的快速检查,证明了我的两个看起来相同的字符串实际上并不等价! - BluDragn
今天我讨厌 JavaScript。我认为这种行为在某个版本的 JavaScript 中发生了改变。我所有以前能够正常工作的代码现在都需要到处使用 trim() - toddmo

18
A1 = "speed"
A2 = "speed" 

if(A1 == A2)  => Error !!!

在控制台中使用以下测试:

escape("speed")

结果: "速度"

escape(A1)

result: "speed%0D" => 这就是问题 %0D !!!

escape(A2)

结果: "速度" => OK !!!

使用正确的代码:

if(A1.slice(0, -1) == A2) This is OK!

2
欢迎来到SO。请格式化您的答案并尽可能提供一些评论。在可能的情况下,提供实际答案而不是伪代码(包括现在)。您的答案应该为其他用户提供有价值的信息,例如新方法或观点,否则它将是多余的。 - M--
2
他们说一张图片等于1000个单词!同样的话也适用于源代码!人们写下他们的想法,但有时候很难理解这些想法以及如何去验证它。对我来说,看三行代码总是比听别人用很多话解释更容易理解。当然,如果没有明显的好处,我就不会再写或评论了。祝好! - Lightlion
注意!现在 escape 已被弃用,取而代之的是 encodeURI https://www.w3schools.com/jsref/jsref_encodeuri.asp - vintagexav

17

我遇到了一个类似的问题,两个明显相同的字符串却不相等,为此我绞尽脑汁想要解决它,最后我这样做了:

for (var c=0; c<string_1.length; c++) {
    if (string_1.charCodeAt(c) != string_2.charCodeAt(c)) {
        alert('c:'+c+' '+string_1.charCodeAt(c)+'!='+string_2.charCodeAt(c));
        valid = false;
    }
}

我发现一个字符串的最后一个字符是10,而另一个字符串的最后一个字符是13,我原以为两个字符串都以空字符结尾,但实际上并不是。


7

我曾经也遇到过同样的问题,后来发现是因为我在比较两个对象。

在这里输入图片描述

要解决这个问题,我不得不使用

JSON.stringify(user._id) === JSON.stringify(userId) // true 

2
避免使用图像。文字更容易被复制和搜索。 - Michael Freidgeim

6
尝试使用===进行精确匹配(类型和值)。这是JavaScript中推荐的比较运算符。
检查字符串的数据类型,确保在两个字符串中都没有隐藏的Unicode或控制字符。

5
我建议您使用normalization,最好是“NFKC”或“NFKD”,因为它们似乎将非断空格规范化为常规空格。
因此,您可以将代码编写为:-
string1.normalize("NFKC") === string2.normalize("NFKC")

3
如果您想使用更简单的方法来处理数字数值,可以使用以下方法:
parseFloat()

完美地发挥作用。

2

在进入该代码块之前,尝试将responseText的值捕获到另一个变量中,以防该变量在其中某个位置更新。

我没有太多直接使用XmlHttpRequest的经验,但我知道Javascript有许多地方使用易变引用来接口对象,这些对象在执行期间可以更改,而不是简单的值。


好主意,但这可能吗?我以为JS是单线程的。 - PhiLho
谢谢你的回答。我理解了,所以我尝试了一下。然而,我们仍然在错误日志中看到“CARD_VALID”,这意味着JS评估('CARD_VALID' == 'CARD_VALID')为false。还有其他想法吗?每天成功数百次,只有一两次出现此问题。唯一的“模式”是对于大多数用户代理都是IE7或IE8,但有一个是IE6... - chaimp

1

强制类型转换对我有用

if (timeSlots[j].id + '' == product.timeSlots[k].id + '') {
}

0
Java Servlet 可以发送字符串,例如:

out.println("CARD_VALID");

或者

out.print("CARD_VALID");

这两个在Javascript中看起来可能一样,但是第一个情况的末尾有空格。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接