在 JavaScript 比较中应该使用哪个等于运算符 (== vs ===)?

Which equals operator (== vs ===) should be used in JavaScript comparisons?

提问人:bcasp 提问时间:12/11/2008 最后编辑:Tarynbcasp 更新时间:5/7/2023 访问量:2118747

问:

这个问题的答案是社区的努力。编辑现有答案以改进此帖子。它目前不接受新的答案或交互。

我正在使用 JSLint 来遍历 JavaScript,并且在执行诸如在语句内部进行比较之类的操作时,它返回了许多建议,将(两个等号)替换为(三个等号)。=====idSele_UNVEHtype.value.length == 0if

替换为 是否有性能优势?=====

任何性能改进都将受到欢迎,因为存在许多比较运算符。

如果没有发生类型转换,性能是否会提高?==

JavaScript 等 相等 标识 运算符

评论


答:

7166赞 Bill the Lizard 12/11/2008 #1

严格相等运算符 () 的行为与抽象相等运算符 () 相同,只是没有进行类型转换,并且类型必须相同才能被视为相等。=====

参考:JavaScript 教程:比较运算符

运算符将在执行任何必要的类型转换后比较是否相等。运算符不会进行转换,因此如果两个值不相同,则类型将仅返回 .两者都同样快。========false

引用 Douglas Crockford 的优秀 JavaScript: The Good Parts

JavaScript 有两组相等运算符:和 ,以及它们的邪恶双胞胎和 。好的按照你所期望的方式工作。如果两个操作数属于同一类型且具有相同的值,则 produce 和 produce .当操作数属于同一类型时,邪恶的双胞胎会做正确的事情,但如果它们属于不同的类型,他们就会试图胁迫这些值。他们这样做的规则是复杂且令人难忘的。以下是一些有趣的案例:===!====!====true!==false

'' == '0'           // false
0 == ''             // true
0 == '0'            // true
false == 'false'    // false
false == '0'        // true
false == undefined  // false
false == null       // false
null == undefined   // true
' \t\r\n ' == 0     // true

Equality Comparison Table

缺乏传递性是令人担忧的。我的建议是永远不要使用邪恶的双胞胎。相反,请始终使用 和 .刚才显示的所有比较都与操作员一起产生。===!==false===


更新

@Casebash在评论和@Phillipe Laybaert 关于对象的回答中提出了一个很好的观点。对于对象,并且彼此一致(特殊情况除外)。=====

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

特殊情况是,当您将基元与由于其 or 方法而计算为同一基元的对象进行比较时。例如,考虑将字符串基元与使用构造函数创建的字符串对象进行比较。toStringvalueOfString

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

在这里,运算符正在检查两个对象的值并返回 ,但看到它们不是同一类型并返回 。哪一个是正确的?这实际上取决于您要比较的内容。我的建议是完全绕过这个问题,不要使用构造函数从字符串文字创建字符串对象。==true===falseString

参考
https://262.ecma-international.org/5.1/#sec-11.9.3

评论

14赞 Ovinus Real 10/11/2020
我还要指出 0 === -0 和 NaN !== NaN,这有时会令人困惑。如果要区分 ±0 并认为 NaN 相等,请使用 Object.is (ES2015)
16赞 aross 3/25/2021
软打字是一项功能。显然,Crockford 指出了设计决策的一些“伪影”,但软类型仍然是一个功能。如果使用得当,绝对可以使用。不要把婴儿和洗澡水一起扔掉。
1赞 Adrian Larson 9/15/2021
为什么需要使用?-0
4赞 Cole Tobin 2/27/2022
@AdrianLarson 这是 IEEE-754 浮点的一个怪癖。它没有实际用途,但由于 IEEE-754“双精度”是“有符号幅度”格式,因此负零“存在”。但是,为了避免意外,它被定义为等于正零。JavaScript(嗯,ECMAScript)将 (-0).toString() 定义为“0”,但并非每种语言都这样做(例如,在 C# 中,是)。这可能会导致奇怪的修复,例如.Math.Round(-0.1).ToString()"-0"x == 0 ? 0 : x
1赞 Ben Voigt 8/10/2022
@Cole:你确定这甚至会产生负零吗?(可能与符号字符是否是 Javascript 文字语法的一部分有关,或者与许多其他语言一样,一元否定是否适用于仅由数字组成的文字)(-0).toString()(-0)-0
1253赞 14 revs, 9 users 30%Kalpesh Rajai #2

使用运算符 (相等==)

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

使用运算符 (Identity===)

true === 1; //false
"2" === 2;  //false

这是因为相等运算符 == 确实类型强制,这意味着解释器在比较之前隐式尝试转换值。

另一方面,恒等运算符 === 不执行类型强制,因此在比较时不会转换值。

评论

5赞 BanksySan 3/24/2022
我不认为身份在这里是正确的术语/检查相等性和类型(称为严格)。标识通常是指“相同性”,它由函数提供(根据 ES2015)。===Object.is
41赞 Sean 12/11/2008 #3

在您的使用中,这两个操作之间不太可能有任何性能差异。无需进行类型转换,因为两个参数已经是同一类型。这两个操作都将进行类型比较,然后进行值比较。

92赞 Doctor Jones 12/11/2008 #4

=== 运算符称为严格比较运算符,它与 == 运算符不同

让我们取 2 个变量 a 和 b。

对于“a == b”,要计算为真,a 和 b 的值必须相同

“a === b”的情况下,a 和 b 必须是相同的值类型,才能计算为 true。

以以下示例为例

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

综上所述;在不希望使用 == 运算符的情况下,使用 == 运算符的计算结果可能会为 true,因此使用 === 运算符会更安全。

在 90% 的使用场景中,使用哪一个并不重要,但是当您有一天遇到一些意外行为时,了解差异会很方便。

50赞 Constantin 12/16/2008 #5

在典型的脚本中,不会有性能差异。更重要的是,千个“===”比千个“==”重 1 KB:)JavaScript 探查器可以告诉您您的情况是否存在性能差异。

但就我个人而言,我会按照 JSLint 的建议去做。之所以提出此建议,不是因为性能问题,而是因为类型强制均值为真。('\t\r\n' == 0)

112赞 Simon Scarfe 12/25/2008 #6

我使用如下代码在Firefox中使用Firebug对此进行了测试:

console.time("testEquality");
var n = 0;
while (true) {
  n++;
  if (n == 100000)
    break;
}
console.timeEnd("testEquality");

console.time("testTypeEquality");
var n = 0;
while (true) {
  n++;
  if (n === 100000)
    break;
}
console.timeEnd("testTypeEquality");

我的结果(每次测试五次并取平均值):

==: 115.2
===: 114.4

所以我想说微小的差异(记住,这是超过 100000 次迭代)可以忽略不计。性能不是这样做的理由。类型安全(嗯,就像你在 JavaScript 中获得的那样安全),代码质量是。===

评论

6赞 Hubert OG 7/14/2013
现在,当运算符存在实际类型强制时,它们如何比较?请记住,这是性能提升的时候。==
3赞 Doug Morrow 7/7/2015
由于上述原因,正确测试时的主要差异是更快地仅检查类型不等式。jsfiddle.net/4jhuxkb2
0赞 Avishay 2/20/2022
我认为我们看到的时间 dif 是因为 n 是一个数字,所以是 100000,您应该在字符串“1”上检查它,我假设会发生一些解析并且时间 dif 会升高
23赞 Thomas Hansen 12/29/2008 #7

问题是你可能很容易遇到麻烦,因为 JavaScript 有很多隐式转换,这意味着......

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

这很快就会成为一个问题。为什么隐式转换是“邪恶”的最佳示例可以从 MFC / C++ 中的这段代码中获取,由于从 CString 到 HANDLE 的隐式转换,它实际上将编译,这是一个指针类型定义类型......

CString x;
delete x;

显然,在运行时,它会做一些非常不确定的事情......

谷歌在 C++ 和 STL 中进行隐式转换,以获得一些反对它的论据......

评论

4赞 Garrett 1/13/2014
0 == null是错误的。
659赞 Philippe Leybaert 6/6/2009 #8

在這裡的答案中,我沒有讀到任何關於平等意義的東西。有人会说这意味着平等和相同类型,但事实并非如此。这实际上意味着两个操作数引用同一个对象,或者在值类型的情况下,具有相同的值===

因此,让我们采用以下代码:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

同样在这里:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

甚至:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

这种行为并不总是显而易见的。这个故事不仅仅是平等和相同类型。

规则是:

对于值类型(数字):
如果 和 具有相同的值且属于同一类型,则返回 true
a === bab

对于引用类型:
如果引用完全相同的对象,则返回 true
a === bab

对于字符串:
如果 和 都是字符串并且包含完全相同的字符,则返回 true
a === bab


字符串:特例...

字符串不是值类型,但在 Javascript 中,它们的行为类似于值类型,因此当字符串中的字符相同且长度相同时,它们将是“相等的”(如第三条规则中所述)

现在它变得有趣:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

但是这个呢?

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

我以为字符串的行为像值类型?好吧,这取决于你问谁......在本例中,a 和 b 不是同一类型。 是类型,而 是类型。请记住,使用构造函数创建字符串对象会创建大多数时候表现为字符串的类型。aObjectbstringStringObject

288赞 nalply 11/29/2009 #9

让我补充一下这个忠告:

如有疑问,请阅读说明书

ECMA-262 是以 JavaScript 为方言的脚本语言的规范。当然,在实践中,最重要的浏览器的行为方式比对如何处理某些东西的深奥定义更重要。但理解为什么 new String(“a”) !== “a” 是有帮助的。

请让我解释一下如何阅读规范来澄清这个问题。我看到在这个非常古老的话题中,没有人对这种非常奇怪的效果有答案。因此,如果您能阅读规范,这将对您的职业有很大帮助。这是一项后天习得的技能。所以,让我们继续。

在 PDF 文件中搜索 === 将我带到规范的第 56 页:11.9.4。严格等于运算符 ( === ),在浏览了规范后,我发现:

11.9.6 严格相等比较算法
比较 x === y,其中 x 和 y 是值,产生。这种比较按如下方式进行:
1.如果 Type(x) 与 Type(y) 不同,则返回 false
2. 如果 Type(x) 为 Undefined,则返回 true
3. 如果 Type(x) 为 Null,则返回 true
4. 如果 Type(x) 不是 Number,请转到步骤 11。
5. 如果 x 是 NaN,则返回 false
6. 如果 y 为 NaN,则返回 false
7. 如果 x 与 y 的数字值相同,则返回 true
8. 如果 x 为 +0 且 y 为 −0,则返回 true
9. 如果 x 为 −0 且 y 为 +0,则返回 true
10. 返回 false
11. 如果 Type(x) 为 String,则如果 x 和 y 是完全相同的字符序列(长度相同,对应位置的字符相同),则返回 true;否则,返回 false
12. 如果 Type(x) 为布尔值,则如果 x 和 y 均为 true 或均为 false,则返回 true;否则,返回 false
13. 如果 x 和 y 引用同一对象,或者它们引用相互连接的对象,则返回 true(参见 13.1.2)。否则,返回 false

有趣的是第 11 步。是的,字符串被视为值类型。但这并不能解释为什么 new String(“a”) !== “a”。我们的浏览器是否不符合 ECMA-262?

没那么快!

让我们检查操作数的类型。通过将它们包装在 typeof() 中来自己尝试一下。我发现new String(“a”)是一个对象,并使用了步骤1:如果类型不同,则返回false

如果你想知道为什么new String(“a”)不返回字符串,那么做一些阅读规范的练习怎么样?玩得愉快!


Aidiakapi 在下面的评论中写道:

从规格

11.2.2 新运算符

如果 Type(constructor) 不是 Object,则引发 TypeError 异常。

换句话说,如果 String 不是 Object 类型,则它不能与 new 运算符一起使用。

new 始终返回一个 Object,即使对于 String 构造函数也是如此。唉!字符串的值语义(请参阅步骤 11)丢失。

这最终意味着:new String(“a”) !== “a”。

89赞 vsync 5/12/2010 #10

===检查相同的边在类型上是否相等。


例:

'1' === 1 // will return "false" because `string` is not a `number`

常见示例:

0 == ''  // will be "true", but it's very common to want this check to be "false"

另一个常见的例子:

null == undefined // returns "true", but in most cases a distinction is necessary

根据我的长期经验,最好使用非类型检查,因为您不在乎值是 、 还是undefinednull0""

另一种比较方法是使用,这里有一个很好的信息答案Object.is

102赞 Dimitar 5/12/2010 #11

在 JavaScript 中,它表示相同的值和类型。

例如

4 == "4" // will return true

4 === "4" // will return false 
109赞 Shiki 5/12/2010 #12

在 PHP 和 JavaScript 中,它是一个严格的相等运算符。这意味着,它将比较类型和值。

56赞 Pop Catalin 5/12/2010 #13

这意味着没有类型强制的相等 类型强制意味着 JavaScript 不会自动将任何其他数据类型转换为字符串数据类型

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 
23赞 Paul Butcher 5/12/2010 #14

来自核心 javascript 参考

===如果操作数严格相等,则返回(见上文) 没有类型转换。true

34赞 Niraj CHoubey 5/12/2010 #15

===运算符检查变量的值和类型是否相等。

==运算符只是检查变量的值是否相等。

34赞 Daniel 5/12/2010 #16

这是一项严格的检查测试。

这是一件好事,尤其是当您在 0 和 false 和 null 之间检查时。

例如,如果您有:

$a = 0;

然后:

$a==0; 
$a==NULL;
$a==false;

所有返回 true,您可能不希望这样做。假设您有一个函数,该函数可以在失败时返回数组的第 0 个索引或 false。如果检查“==”false,则可能会得到令人困惑的结果。

所以与上面的东西相同,但要严格测试:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false

评论

3赞 Ry- 5/6/2013
在 JavaScript 中,这是完全错误的,而且是错误的不完整。.-10 != null
48赞 CuongHuyTo 9/16/2011 #17

等式比较运算符 == 令人困惑,应避免使用。

如果你必须忍受它,那么请记住以下 3 件事:

  1. 它不是传递的:(a == b) 和 (b == c) 不会导致 (a == c
  2. 它与否定是互斥的:(a == b) 和 (a != b) 始终保持相反的布尔值,所有 a 和 b
  3. 如有疑问,请牢记以下真相表:

JAVASCRIPT 中的相等运算符真值表

  • 表中的每一行都是一组 3 个相互“相等”的值,这意味着其中任何 2 个值都使用等号 ==* 相等

** 奇怪:请注意,从这个意义上说,第一列上的任何两个值都不相等。

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.
33赞 ashes 6/5/2012 #18

JSLint 有时会给你一些不切实际的理由来修改东西。 具有完全相同的性能,就好像类型已经相同一样。=====

只有当类型不同时,它才会更快,在这种情况下,它不会尝试转换类型,而是直接返回 false。

所以,恕我直言,JSLint 可能用于编写新代码,但应不惜一切代价避免无用的过度优化。

这意味着,没有理由在检查中更改为,就像你知道 a 只能是字符串这一事实一样。=====if (a == 'test')

以这种方式修改大量代码会浪费开发人员和审阅者的时间,并且一无所获。

评论

0赞 aross 3/25/2021
有趣的是,在Firefox中实际上比.无论如何,这都是一种微优化,但这与人们声称的相反。a.length===4a.length==4
39赞 mar10 4/27/2013 #19

根据经验,我通常会使用 instead 而不是 (and instead of )。=====!==!=

原因在上面的答案中得到了解释,道格拉斯·克罗克福德(Douglas Crockford)也非常清楚(JavaScript:好的部分)。

但是,有一个例外:是检查“为 null 或未定义”的有效方法:== null

if( value == null ){
    // value is either null or undefined
}

例如,jQuery 1.9.1 使用了 43 次这种模式,JSHint 语法检查器甚至为此提供了宽松选项。eqnull

jQuery风格指南中:

应使用严格的相等性检查 (===) 来支持 ==。唯一的 异常是通过 null 检查 undefined 和 null 时。

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

编辑 2021-03:

如今,大多数浏览器都支持 Nullish 合并运算 (??) 和逻辑 nullish 赋值 (??=),这允许更简洁的方式 如果变量为 null 或未定义,则分配默认值,例如:

if (a.speed == null) {
  // Set default if null or undefined
  a.speed = 42;
}

可以写成这些形式中的任何一种

a.speed ??= 42;
a.speed ?? a.speed = 42;
a.speed = a.speed ?? 42;

评论

1赞 Sebastian Simon 3/15/2021
== null 是检查'是 null 还是未定义'的有效方法”......document.all
58赞 user2496033 7/3/2013 #20

JavaScript .=====

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type
26赞 Harry He 9/9/2013 #21

前 2 个答案都提到了 == 表示平等,=== 表示身份。不幸的是,这种说法是不正确的。

如果 == 的两个操作数都是对象,则对它们进行比较以查看它们是否是同一个对象。如果两个操作数都指向同一对象,则相等运算符返回 true。否则 两者并不相等。

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

在上面的代码中,== 和 === 都为 false,因为 a 和 b 不是同一个对象。

也就是说:如果 == 的两个操作数都是对象,则 == 的行为与 === 相同,这也意味着同一性。这两个运算符的本质区别在于类型转换。== 在检查相等性之前具有转换,但 === 没有。

22赞 user2601995 10/3/2013 #22

相等性比较:

算子==

当两个操作数相等时,返回 true。在进行比较之前,操作数将转换为相同的类型。

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

相等性和类型比较:

算子===

如果两个操作数相等且类型相同,则返回 true。一般来说 如果以这种方式进行比较,则更好更安全,因为没有幕后类型转换。

>>> 1 === '1'
false
>>> 1 === 1
true
18赞 Mr.G 3/19/2014 #23

*运算符 === vs == *

1 == true    =>    true
true == true    =>    true
1 === true    =>    false
true === true    =>    true
21赞 Christian Hagelid 3/27/2014 #24

这是一个方便的比较表,显示了发生的转换以及 和 之间的差异。=====

正如结论所述:

“除非您完全了解所需的转换,否则请使用三个等号 两个平等的地方。

http://dorey.github.io/JavaScript-Equality-Table/

21赞 2 revs, 2 users 69%vivek_nk #25

null 和 undefined 是虚无的,即

var a;
var b = null;

这里没有值。而 0、false 和 '' 都是值。所有这些共同点是它们都是虚假值,这意味着它们都满足虚假条件。ab

因此,0、false 和 '' 一起形成一个子组。另一方面,null 和 undefined 构成了第二个子组。检查下图中的比较。null 和 undefined 相等。其他三个将彼此相等。但是,它们在 JavaScript 中都被视为虚假条件。

Enter image description here

这与任何对象(如{},数组等)相同,非空字符串和布尔值true都是真条件。但是,它们都不是平等的。

891赞 SNag 5/5/2014 #26

这是 和 之间的相等性比较的有趣可视化。=====

来源:https://github.com/dorey/JavaScript-Equality-Tabledemo统一demo)


var1 === var2

当用于 JavaScript 相等性测试时,一切都是原样的。
在评估之前,不会转换任何内容。
===

Equality evaluation of === in JS

var1 == var2

当用于 JavaScript 相等性测试时,会发生一些时髦的转换==

Equality evaluation of == in JS

Javascript 中的平等总结

Equality in Javascript


结论:

始终使用 ===,除非您完全理解 .==

评论

10赞 rocketsarefast 5/24/2021
一个更好的“==”表:algassert.com/visualization/2014/03/27/...
0赞 imkzh 11/30/2021
至少 == 比较是可交换的(即 (a==b) === (b==a)) XD
0赞 Feuermurmel 4/20/2022
@imkzh 关系通常被称为对称关系,而不是交换关系。但我来这里到底想说的是:不是及物的!(即使忽略==NaN)
0赞 SNag 4/21/2022
@Feuermurmel:您能举例说明什么时候是不可传递的吗?==
0赞 Feuermurmel 4/27/2022
哦,对不起,回复晚了。@SNag当然。取 、 和 。a = []b = falsec = [0]
18赞 garakchy 8/9/2014 #27

JavaScript 既有严格的比较,也有类型转换的比较。严格比较(例如,)只有在操作数属于同一类型时才成立。更常用的抽象比较(例如)在进行比较之前将操作数转换为相同的类型。=====

  • 如果操作数不是同一类型,则 equality () 运算符会转换它们,然后应用严格的比较。如果操作数是数字或布尔值,则操作数将尽可能转换为数字;否则,如果任一操作数是字符串,则字符串操作数将尽可能转换为数字。如果两个操作数都是对象,则 JavaScript 会比较内部引用,当操作数引用内存中的同一对象时,这些引用是相等的。==

    语法:

    x == y

    例子:

    3 == 3     // true
    "3" == 3   // true
    3 == '3'   // true
    
  • 如果操作数严格相等(见上文),并且没有类型转换,则 identity/strict equality() 运算符返回 true。===

    语法:

    x === y

    例子:

    3 === 3 // true

供参考:比较运算符(Mozilla Developer Network)

40赞 Aniket Thakur 11/14/2014 #28

是的!这确实很重要。

===JavaScript 中的运算符检查值类型,而 AS 运算符只检查值(如果需要,进行类型转换)。==

enter image description here

您可以轻松测试它。将以下代码粘贴到 HTML 文件中,然后在浏览器中打开它

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

您将在警报中得到“false”。现在修改方法,你会得到onPageLoad()alert(x == 5);

17赞 Sake Salverda 11/29/2014 #29

如果您正在制作 Web 应用程序或安全页面,您应该始终使用(仅在可能的情况下)

===

因为它会检查它是否是相同的内容以及它是否是相同的类型!

因此,当有人输入时:

var check = 1;
if(check == '1') {
    //someone continued with a string instead of number, most of the time useless for your webapp, most of the time entered by a user who does not now what he is doing (this will sometimes let your app crash), or even worse it is a hacker searching for weaknesses in your webapp!
}

但随着

var check = 1;
if(check === 1) {
    //some continued with a number (no string) for your script
} else {
    alert('please enter a real number');
}

黑客永远不会深入系统来发现错误并入侵您的应用程序或用户

我的观点是,

===

将为您的脚本增加更多安全性

当然,您也可以检查输入的数字是否有效,是否为字符串等。在第一个示例中使用其他 if 语句,但这至少对我来说更容易理解和使用

我发布这篇文章的原因是,在这次对话中从未说过“更安全”或“安全性”这个词(如果你看一下它使用 2019 次 === 和 1308 次 == iCloud.com,这也意味着你有时会使用 == 而不是 ===,否则它会阻止你的功能,但正如开头所说,你应该尽可能多地使用 ===)

41赞 Amit 3/20/2015 #30

只是

==表示具有类型强制的操作数之间的比较

===表示没有类型强制的操作数之间的比较

JavaScript 中的类型强制意味着自动将数据类型转换为其他数据类型。

例如:

123 == "123"  // Returns true, because JS coerces string "123" to number 123
              // and then goes on to compare `123 == 123`.

123 === "123" // Returns false, because JS does not coerce values of different types here.
12赞 hopper #31

===关心对象是否相同。因此,返回 false。但是,不关心对象是否相同;它只是简单地将一个参数转换为另一个参数的类型:如果无法转换,则返回 false。然后返回 true 而不是 false。new String("Hello world") === "Hello world"==new String("Hello world") == "Hello world"

评论

0赞 Sebastian Simon 3/15/2021
这个答案有点误导,或者至少不是很精确......“对象”?你是说“类型”吗? 确实在乎类型是否相同;如果是,它委托给严格的相等比较。通过引用比较两个对象,但两个运算符都是这种情况。“如果无法转换”——我猜......但胁迫通常是可能的,这不足以导致比较的一个或另一个结果,例如,即使胁迫是可能的。=="undefined" != undefined
29赞 Vikas 5/14/2015 #32

一个简单的例子是

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.
11赞 Akshay Khale 7/22/2015 #33

javascript 是一种弱类型语言,即没有任何数据类型,如 C、c++ 等。int、boolean、float 等,因此变量可以保存任何类型的值,这就是为什么这些特殊的比较运算符存在的原因

例如

var i = 20;var j = "20";

如果我们应用比较运算符,这些变量的结果将是

i==j //result is true

j != i//result is false

为此,我们需要一个特殊的比较运算符来检查变量的值和数据类型

如果我们这样做

i===j //result is false
13赞 CodeFarmer 8/6/2015 #34

我的推理过程使用 emacs 组织模式和 node.js 来运行测试。

| use ==     | '' | '0' | false | 'false' | undefined | null | ' \t\r\n ' |
| ''         | x  | f   | t     | f       | f         | f    | f          |
| '0'        |    | x   | t     | f       | f         | f    | f          |
| false      |    |     | x     | f       | f         | f    | t          |
| 'false'    |    |     |       | x       | f         | f    | f          |
| undefined  |    |     |       |         | x         | t    | f          |
| null       |    |     |       |         |           | x    | f          |
| ' \t\r\n ' |    |     |       |         |           |      | x          | 



| use ===    | '' | '0' | false | 'false' | undefined | null | ' \t\r\n ' |
| ''         | x  | f   | f     | f       | f         | f    | f          |
| '0'        |    | x   | f     | f       | f         | f    | f          |
| false      |    |     | x     | f       | f         | f    | f          |
| 'false'    |    |     |       | x       | f         | f    | f          |
| undefined  |    |     |       |         | x         | f    | f          |
| null       |    |     |       |         |           | x    | f          |
| ' \t\r\n ' |    |     |       |         |           |      | x          |

我的测试脚本如下:运行>节点xxx.js

var rowItems = ['', '0', false, 'false', undefined, null, ' \t\r\n ']
var colItems = rowItems

for(var i = 0; i < rowItems.length; i++) {
    for (var j = 0; j < colItems.length; j++) {
        var r = (rowItems[i] === colItems[j]) ? true : false;
        console.log(rowItems[i] + " = " + colItems[j] + " " + r + " [" + i + "] ==> [" + j + "]")
    };
}
76赞 Samar Panda 9/5/2015 #35

严格相等的 Javascript 执行流程图 / 比较 '==='

Javascript strict equality

非严格相等/比较 '==' 的 Javascript 执行流程图

Javascript non equality

5赞 Dmitri Pavlutin 1/4/2016 #36

是的,平等运算符和身份运算符之间有很大的区别。
通常,标识运算符的执行速度更快,因为没有进行类型转换。但是,如果值属于同一类型,则不会看到任何差异。
查看我的帖子 JavaScript 相等运算符的图例,其中解释了详细信息,包括类型转换和比较算法,并提供了大量示例。
=====

5赞 Alex Gray 5/15/2016 #37

使用的一个未提及的原因是,如果您与 /交叉编译 to/from 共存。摘自 CoffeeScript 上的小书...===coffee-script

JavaScript 中的弱相等比较有一些令人困惑的行为,通常是令人困惑的错误的根源。

解决方案是改用严格的相等运算符,它由三个等号组成:===。它的工作方式与普通相等运算符完全相同,但没有任何类型强制。建议始终使用严格的相等运算符,并在需要时显式转换类型。

如果您经常与 进行转换,则应仅使用 .事实上,编译器会强迫你...coffee-script===coffee-script

CoffeeScript 解决了这个问题,只需将所有弱比较替换为严格比较,换句话说,将所有 == 比较器转换为 ===。您不能在 CoffeeScript 中进行弱相等性比较,如有必要,您应该在比较类型之前显式转换类型。

7赞 Alexandr 7/1/2016 #38

始终使用“===”,您将避免数千个错误。如今,使用三重相等性更适合不同的风格指南,因为它比较考虑了操作数的类型。

1赞 yanguya995 7/2/2016 #39

Javascript 是松散类型的,就像 php 一样,

var x = "20";
var y =20;

if (x===y) // false

这总是会给你一个假,因为即使变量的值相同,数据类型也不是

一个是字符串,另一个是 int

If(x==y)//true

然而,这只会检查内容是否相同,而不管数据类型如何......

我不想说这些值相等,因为字符串值在逻辑上不能等于 int 值

0赞 Orri Scott 7/5/2016 #40
var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

在其中一个答案中看到了这一点。 并且在这种情况下不是真正的同一类型,如果您进行检查,您将获得“object”并且是“string”。abtypeof(a)typeof(b)

99赞 Luis Perez 8/10/2016 #41

为什么 == 如此不可预测?

当你将空字符串与数字零进行比较时,你会得到什么?""0

true

是的,没错,根据空字符串和数字零是同一时间。==

它并没有就此结束,这是另一个:

'0' == false // true

数组的事情变得非常奇怪。

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

然后用字符串更奇怪

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

情况变得更糟:

什么时候等于不等于?

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

让我再说一遍:

(A == B) && (B == C) // true
(A == C) // **FALSE**

而这只是你从基元中得到的疯狂的东西。

当您与对象一起使用时,这是一个全新的疯狂水平。==

在这一点上,你可能想知道......

为什么会这样?

嗯,这是因为与“三等”()不同,它只是检查两个值是否相同。===

==一大堆其他事情

它对函数有特殊处理,对空值、未定义、字符串等进行特殊处理。

它变得非常古怪。

事实上,如果你尝试编写一个函数来执行该操作,它将看起来像这样:==

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);
    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

那么这意味着什么呢?

这意味着很复杂。==

因为它很复杂,所以很难知道使用它时会发生什么。

这意味着您最终可能会遇到错误。

所以这个故事的寓意是......

让你的生活不那么复杂。

使用代替 .=====

结束。

2赞 Rotimi 4/24/2017 #42

首先,关于 Javascript 字符串等于的一些术语:Double equals 被正式称为抽象相等比较运算符,而 triple equals 被称为严格的相等比较运算符。它们之间的区别可以总结如下:抽象相等将尝试在进行比较之前通过类型强制来解析数据类型。如果类型不同,严格相等将返回 false。请看以下示例:

console.log(3 == "3"); // true
console.log(3 === "3"); // false.
console.log(3 == "3"); // true
console.log(3 === "3"); // false.

使用两个等号返回 true,因为在进行比较之前,字符串“3”已转换为数字 3。三个等号表示类型不同并返回 false。这是另一个:

console.log(true == '1'); // true
console.log(true === '1'); // false
console.log(true == '1'); // true
console.log(true === '1'); // false

同样,抽象相等性比较执行类型转换。在这种情况下,布尔值 true 和字符串 '1' 都转换为数字 1,结果为 true。严格相等返回 false。

如果你明白你正在区分 == 和 ===。但是,在某些情况下,这些运算符的行为并不直观。让我们再看一些例子:

console.log(undefined == null); // true
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.
console.log(undefined == null); // true     
console.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.

console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false
console.log(true == 'true'); // false. A string will not be converted to a boolean and vice versa.
console.log(true === 'true'); // false

下面的示例很有趣,因为它说明了字符串文本不同于字符串对象。

console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
console.log("This is a string." == new String("This is a string.")); // true
console.log("This is a string." === new String("This is a string.")); // false
11赞 Sharad Kale 4/28/2017 #43

==运算符只是比较值而不是数据类型。

===运算符将值与其数据类型进行比较。

例如:

1 == "1" //true

1 === "1" //false

此运算符 () 用于执行自动类型转换的语言,例如。PHP,Javascript。
运算符有助于防止自动类型转换导致的意外比较。
"===""==="

评论

0赞 mrmr68 5/25/2017
对于“==”,数据类型并不重要
0赞 Sebastian Simon 5/23/2020
@mrmr68 抽象相等比较的操作数类型非常重要——它用于将操作数强制转换为其他类型,以便可以进行比较。
1赞 Alireza 5/7/2017 #44

如果你想在 JavaScript 中比较一些东西,请使用它,它被称为严格相等,这意味着如果只有类型和值都相同,这将返回 true,所以不会有任何不需要的类型更正,如果你使用 ,你基本上不关心类型,在许多情况下你可能会遇到松散相等性比较的问题。=====

严格相等使用 ===

严格相等比较两个相等值。这两个值都不是 在进行比较之前隐式转换为其他值。如果 值具有不同的类型,这些值被认为是不相等的。 否则,如果值具有相同的类型并且不是数字, 如果它们具有相同的值,则它们被视为相等。最后,如果两者兼而有之 值是数字,如果它们都不是 NaN,则认为它们相等 并且是相同的值,或者如果一个是 +0 而一个是 -0。

var num = 0;
var obj = new String('0');
var str = '0';

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false


使用 == 的松散相等

松散相等在转换两个值后比较两个值是否相等 值设置为通用类型。转换后(一侧或两侧可能 进行转换),执行最终的相等性比较 完全按照 === 执行它。松散相等是对称的:A == B 对于 A 和 B 的任何值,始终与 B == A 具有相同的语义 (应用转换的顺序除外)。

var num = 0;
var obj = new String('0');
var str = '0';

console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true

console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true

// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);

评论

0赞 sramzan 5/18/2017
我确实相信,关于你应该/不应该做什么是主观的,并且告诉某人总是使用特定动作是误导性的。虽然我同意在大多数情况下,我们倾向于使用“===”与“==”,但可能存在一种特殊情况,您希望完成类型转换。- 我无法从我的脑海中想出一个确切的用例,但也许设计是为了进行松散的检查。无论如何,如果语言中包含某些内容,那么它的存在是有原因的。在我看来,我们应该尽量避免笼统地陈述“总是做x”。
0赞 Alireza 5/19/2017
我同意你的看法,如果你读了我的整个答案,你会看到我稍后会更详细地解释,老实说,我们在 Javascript 中使用的情况并不多,需要松散的比较......我可以说不到 5%,甚至更少,但我对那些没有 js 背景的人使用“总是”,他们认为 == 检查 JavaScript 中的严格比较,他们学会了猫腻,一开始就不使用它,但随着他们变得更加专业,他们知道在哪些罕见情况下他们可能会使用它。这就是为什么我这样写我的答案。
8赞 RïshïKêsh Kümar 6/25/2017 #45

不同于 、 、== == = =

  • =operator 用于仅分配 .value
  • = =operator 用于仅比较 notvaluesdatatype
  • = = =operator 用于比较 以及 。valuesdatatype
1赞 Narendra Kalekar 8/1/2017 #46

建议替换为的原因是运算符比 更可靠。在我们的上下文中,可靠的方法也适用于类型检查。考虑到最佳编程实践,我们应该始终选择更可靠的功能,而不是不太可靠的功能。同样,每当我们大多数时候考虑与运算符完全相等时,我们默认认为类型应该相同。提供相同的条件,我们应该去做。================

2赞 Neil Meyer 11/16/2017 #47

严格平等在大多数情况下更好

Javascript 是一种松散类型的语言,当你使用它时,它需要不断出现在你的脑海中。只要数据结构相同,就没有理由不使用严格的相等,对于常规相等,您通常会自动进行值的隐式转换,这会对您的代码产生深远的影响。这种转换很容易出现问题,因为它们会自动发生。

在严格相等的情况下,没有自动隐式转换,因为值必须已经具有正确的数据结构。

1赞 Bekim Bacaj 11/27/2017 #48

“我应该使用还是在 JavaScript 中进行比较”的困境等于或类似于以下问题:“我应该使用'勺子'还是'叉子'吃饭。=====

这个问题唯一合理的答案是

  1. 您应该使用动态类型比较,例如:用于松散类型比较。==
  2. 您应该使用静态类型比较,例如:用于强类型比较。===

那是因为它们不一样。它们没有相同的目的,也不打算用于相同的目的。

当然,“叉子”和“勺子”都是用来“吃”的,但你会根据你吃的东西来选择使用它们。

意思是:你会下定决心使用“勺子”,即:用于“汤”,和/或“叉子”,即:用于采摘。=====

问使用“叉子”还是“勺子”来“吃饭”更好 - 等于问在 JS 中使用静态 [===] 和动态 [==] 等式更好。这两个问题同样是错误的,反映了对有关主题的非常狭隘或肤浅的理解。

评论

0赞 Bekim Bacaj 12/6/2017
p.s.:JSLint(或 Crockford)在处理相同类型的值时坚持或要求您使用严格的类型比较是错误的。JavaScript 属性的类型始终为:number。因此,没有假阳性的余地或可能性。此外,没有必要使用直接的简写来代替。lengthdSele_UNVEHtype.value.length === 0!dSele_UNVEHtype.value.length
3赞 Jasper 12/22/2017
你为什么要回答一个 9 年前的问题,它已经有 49 个答案,也有一个超过 5k 个赞成票的接受答案,答案包含一个奇怪的类比,并且没有解释任何尚未说过的东西?
2赞 Bekim Bacaj 12/26/2017
因为 JavaScript 有很多专业误用,无论它们有多老。例如,您无法理解它的全部内容,也无法捕捉到 Live Script 与静态类型语言相比所区别的本质。为什么我们需要它的智能动态。JavaScript 是为有创造力、聪明的人制作的,而不是为笨蛋制作的。
2赞 Jasper 12/27/2017
是的,我同意有很多对 JavaScript 的误用。但是,我仍然认为您的类比很奇怪,因为它很容易被误解,并且它没有以有意义的方式涵盖核心基础知识。
0赞 Bekim Bacaj 12/29/2017
给出的类比是它们差异和用例质量的最佳例证。这是最好的短文,即使你是JS的新手,也能学习绝对的本质。并且同样好,可能比我后来关于如何清空 JS 数组 [真正] 的答案要好。