在 JavaScript 比较中应该使用哪个相等运算符(== 还是 ===)?

我正在使用JSLint来浏览 JavaScript,当在if语句中比较idSele_UNVEHtype.value.length == 0时,它会返回许多建议来将==(两个等号)替换为===(三个等号)。

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

由于存在许多比较运算符,因此欢迎任何性能改进建议。

如果没有进行类型转换,是否会有超过==的性能提升?

2062705 次浏览

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

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

==运算符将比较是否相等在进行任何必要的类型转换之后===运算符将没有进行转换,因此如果两个值的类型不相同,===将简单地返回false。两者都同样快。

引用道格拉斯·克罗克福德的名言JavaScript:好的部分

JavaScript有两组相等运算符:===!==,以及它们的邪恶双胞胎==!=。好的运算符按照你预期的方式工作。如果两个操作数具有相同的类型并具有相同的值,那么===产生true!==产生false。当操作数类型相同时,邪恶双胞胎会做正确的事情,但如果它们类型不同,它们会试图强制执行值。他们这样做的规则很复杂,令人难忘。这些是一些有趣的案例:

'' == '0'           // false0 == ''             // true0 == '0'            // true
false == 'false'    // falsefalse == '0'        // true
false == undefined  // falsefalse == null       // falsenull == undefined   // true
' \t\r\n ' == 0     // true

等式对照表

缺乏传递性令人担忧。我的建议是永远不要使用邪恶的双胞胎。相反,总是使用===!==。刚才显示的所有比较都产生了===运算符的false


更新时间:

@陈志立在评论中提出了一个很好的观点,在@菲利普·莱伯特回答中提到了对象。对于对象,=====相互一致(除非在特殊情况下)。

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            // falsea === b           // false
c == d            // falsec === d           // false
e == f            // truee === f           // true

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

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

这里==运算符检查两个对象的值并返回true,但是===看到它们不是相同的类型并返回false。哪一个是正确的?这真的取决于你想比较什么。我的建议是完全绕过这个问题,不要使用String构造函数从字符串文字创建字符串对象。

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

使用==运算符(平等

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

使用===运算符(身份

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

这是因为等号操作符#0执行强制类型,这意味着解释器在比较之前隐式地尝试转换值。

另一方面,标识运算符#0不进行类型强制,因此在比较时不转换值。

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

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

取2个变量a和b。

对于"a==b"评估为true 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%的使用场景中,你使用哪一个并不重要,但是当你有一天遇到一些意想不到的行为时,知道区别是很方便的。

在典型的脚本中,没有性能差异。更重要的可能是千 "===" 比千重1 KB "==" :) JavaScript分析器可以告诉您在您的情况下是否存在性能差异。

但就我个人而言,我会按照JSLint的建议去做。这个建议的存在不是因为性能问题,而是因为类型强制意味着('\t\r\n' == 0)为真。

我在FirefoxFirebug中使用这样的代码进行了测试:

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中一样安全),代码质量是。

问题是您可能很容易陷入困境,因为JavaScript有很多隐式转换,这意味着…

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

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

CString x;delete x;

显然,在运行时非常未定义的事情…

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

在这里的答案中,我没有读到任何关于平等的意思。有些人会说===意味着相同的和相同类型的,但事实并非如此。它实际上意味着两个操作数引用同一个对象,或者在值类型,具有相同的值的情况下。

所以,让我们使用以下代码:

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

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

规则是:

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

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

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


字符串:特殊情况…

字符串不是值类型,但在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不是同一个类型。a是类型Object,而b是类型string。请记住,使用String构造函数创建字符串对象会创建类型Object的东西,其行为类似于字符串大部分时间

让我补充一下这个建议:

如果有疑问,请阅读规范

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

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

在PDF文件中搜索===将我带到规范的第56页:11.9.4.严格等于运算符 ( === ),在仔细阅读规范后,我发现:

11.9.6严格等式比较算法
比较x===y,其中x和y是值,产生真正虚假。这样的比较执行如下:
  1.如果Type(x)与Type(y)不同,则返回虚假
  2.如果Type(x)未定义,则返回真正
  3.如果Type(x)为Null,则返回真正
  4.如果Type(x)不是Number,请转到步骤11。
  5.如果x是NaN,返回虚假
  6.如果y是NaN,返回虚假
  7.如果x与y的数值相同,则返回真正
  8.如果x是+0,y是−0,返回真正
  9.如果x是−0,y是+0,返回真正
  10.返回虚假
  11.如果Type(x)是String,如果x和y是完全相同的字符序列(相同的长度和相应位置的相同字符),则返回真正;否则,返回虚假
  12.如果Type(x)是布尔值,如果x和y都是真正或都是虚假,则返回真正;否则,返回虚假
  13.如果x和y指的是同一个对象,或者它们指的是相互连接的对象,则返回真正(见13.1.2)。否则,返回虚假

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

别那么快!

让我们检查操作数的类型。通过将它们包装在typeof()中亲自尝试。我发现新字符串("a")是一个对象,使用了步骤1:如果类型不同,则返回虚假

如果您想知道为什么新字符串("a")不返回字符串,那么阅读规范的一些练习怎么样?玩得开心!


艾迪亚卡皮在下面的评论中写道:

从规格

11.2.2新运营商

如果Type(构造函数)不是Object,则抛出TypeError异常。

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

新的总是返回一个Object,即使对于String构造函数也是如此。唉!字符串的值语义学(参见步骤11)丢失了。

这最后意味着:New String("a";) ! == "; a"

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


示例:

'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还是""

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

例如,

4 == "4" // will return true

4 === "4" // will return false

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

它意味着没有类型强制的相等类型强制意味着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 butjavaScript convert 2 to string by using == operator
2==='2'  //false because by using === operator ,javaScript do not convertinteger to string
2===2   //true because both have same value and same types

核心javascript参考

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

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

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

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

这是一件好事,特别是如果你在0和false和null之间进行检查。

例如,如果您有:

$a = 0;

然后:

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

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

同样的事情,但一个严格的测试:

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

相等的比较运算符==令人困惑,应该避免。

如果你和它一起生活,那么记住以下三件事:

  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 aboveNaN                // NaN is not equal to any thing, even to itself.

JSLint有时会给你不切实际的理由来修改东西。如果类型已经相同,===的性能与==完全相同。

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

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

也就是说,没有理由在像if (a == 'test')这样的检查中将==更改为===,因为您知道a只能是字符串。

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

根据经验,我通常使用===而不是==(和!==而不是!=)。

原因在上面的答案中解释过,道格拉斯·克罗克福德对此也很清楚(JavaScript:好的部分)。

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

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

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

jQuery样式指南

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

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

编辑2021-03:

现在大多数浏览器支持零合并运算符(#0)逻辑空赋值#0,它允许更简洁的方式来如果变量为空或未定义,则分配默认值,例如:

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

可以写成以下任何一种形式

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

JavaScript===vs==

0==false   // true0===false  // false, because they are of a different type1=="1"     // true, auto type coercion1==="1"    // false, because they are of a different type

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

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

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

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

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

相等比较:

操作符==

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

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

等式和类型比较:

操作符===

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

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

*运算符===vs == *

1 == true    =>    truetrue == true    =>    true1 === true    =>    falsetrue === true    =>    true

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

如结论所述:

"使用三个等于,除非你完全理解需要的转换”““两个相等的地方。

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

空和未定义是虚无,也就是说,

var a;var b = null;

这里ab没有值。而0、false和"都是值。所有这些之间的一个共同点是它们都是假值,这意味着它们都是满足假条件。

所以,0、false和"一起形成了一个子组。另一方面,null&untex形成了第二个子组。检查下图中的比较。null和未定义将相等。其他三个将彼此相等。但是,它们在JavaScript中都被视为false sy条件。

在此处输入图像描述

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

这是=====之间平等比较的有趣可视化。

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


var1 === var2

当使用===进行JavaScript相等性测试时,一切都保持原样。
在评估之前不会转换任何内容。

===在JS中的相等性评估

var1 == var2

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

==在JS中的相等性评估

Javascript中的平等摘要

JavaScript中的平等


结论:

总是使用#0,除非你完全理解==发生的时髦的转换

JavaScript有严格比较和类型转换比较。严格比较(例如===)仅在操作数类型相同时为真。更常用的抽象比较(例如==)在进行比较之前将操作数转换为相同的类型。

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

    语法:

    x == y

    示例:

    3 == 3     // true"3" == 3   // true3 == '3'   // true
  • The identity/strict equality(===) operator returns true if the operands are strictly equal (see above) with no type conversion.

    Syntax:

    x === y

    Examples:

    3 === 3 // true

For reference: Comparison operators (Mozilla Developer Network)

耶!这很重要。

JavaScript检查值以及类型中的===运算符,其中==运算符只是检查值(如果需要,是否进行类型转换)

输入图片描述

您可以轻松地测试它。将以下代码粘贴到超文本标记语言文件中并在浏览器中打开它

<script>
function onPageLoad(){var x = "5";var y = 5;alert(x === 5);};
</script>
</head>
<body onload='onPageLoad();'>

您将获得“虚假”警报。现在将onPageLoad()方法修改为alert(x == 5);,您将获得真正

如果您正在制作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语句一起,但这至少对我来说更容易理解和使用

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

简单

==表示操作数之间的比较类型强制转换

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

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.

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

一个简单的例子是

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

javascript是一个弱类型语言,即没有任何数据类型,如C中的数据类型,c++例如int,布尔值,浮点数等,因此变量可以保存任何类型的值,这就是为什么有这些特殊的比较运算符

eg

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

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

i==j //result is true

j != i//result is false

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

如果我们这样做

i===j //result is false

我的推理过程使用emacs org模式和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          |

我的测试脚本如下:run>nodexxx.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 + "]")};}

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

JavaScript严格相等

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

JavaScript非相等

是的,相等==和身份===运算符之间有很大的区别。
通常身份运算符执行得更快,因为没有进行类型转换。但是如果值的类型相同,您将看不到任何区别。
查看我的帖子JavaScript等号操作符,它解释了细节,包括类型转换和比较算法,还有很多例子。

一个未提及的使用===的原因-是在您与/交叉编译到/来自coffee-script的情况下。从关于CoffeeScript的小书

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

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

如果您经常与coffee-script进行转换,您应该只使用===。事实上,coffee-script编译器将迫使你

CoffeeScript通过简单地将所有弱比较替换为严格比较来解决这个问题,换句话说,将所有==比较器转换为===。您不能在CoffeeScript中进行弱相等比较,如果有必要,您应该在比较它们之前显式转换类型。

总是使用===,你将避免成千上万的错误。如今,使用三倍相等性在不同的样式指南中更可取,因为它考虑了操作数的类型。

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

var x = "20";var y =20;
if (x===y) // false

这将始终为您提供false,因为即使变量的值相同,数据类型也不相同

一个是string,另一个是int

If(x==y)//true

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

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

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

在其中一个答案中看到了这一点。在这种情况下,如果您检查typeof(a)ab实际上不是同一类型你会得到对象typeof(b)字符串

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

当您将空字符串""与数字零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 stringlet B = 0   // zerolet 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 functionif(typeof y === typeof x) return y === x;// treat null and undefined the samevar 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 compareif(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 "+" trickif(typeof x !== "number") x = +x;if(typeof y !== "number") y = +y;// actually the real `==` is even more complicated than this, especially in ES6return x === y;}
function toPrimitive(obj) {var value = obj.valueOf();if(obj !== value) return value;return obj.toString();}

那么这意味着什么呢?

这意味着==很复杂。

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

这意味着你可能会以错误告终。

所以这个故事的寓意是…

让你的生活不那么复杂。

使用===而不是==

结束。

双等号被正式称为抽象相等比较运算符,而三等号被称为严格相等比较运算符。它们之间的区别可以总结如下:

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

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

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

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

如果你明白你已经很好地区分了==和===。但是,在某些情况下,这些运算符的行为并不直观。让我们看更多的例子:

console.log(undefined == null); // trueconsole.log(undefined === null); // false. Undefined and null are distinct types and are not interchangeable.console.log(undefined == null); // trueconsole.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'); // falseconsole.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.")); // trueconsole.log("This is a string." === new String("This is a string.")); // falseconsole.log("This is a string." == new String("This is a string.")); // trueconsole.log("This is a string." === new String("This is a string.")); // false

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

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

eg:

1 == "1" //true
1 === "1" //false

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

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

使用===的严格相等

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

var num = 0;var obj = new String('0');var str = '0';
console.log(num === num); // trueconsole.log(obj === obj); // trueconsole.log(str === str); // true
console.log(num === obj); // falseconsole.log(num === str); // falseconsole.log(obj === str); // falseconsole.log(null === undefined); // falseconsole.log(obj === null); // falseconsole.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); // trueconsole.log(obj == obj); // trueconsole.log(str == str); // true
console.log(num == obj); // trueconsole.log(num == str); // trueconsole.log(obj == str); // trueconsole.log(null == undefined); // true
// both false, except in rare casesconsole.log(obj == null);console.log(obj == undefined);

不同的是== == = =

  • =运算符用于仅分配value
  • = =运算符用于比较values而不是datatype
  • = = =运算符用于比较valuesdatatype

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

严格的平等在很大程度上更好

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

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

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

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

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

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

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

意思是:你将决定使用“勺子”,即:==来喝“汤”,和/或“叉子”,即:===来采摘。

询问是否使用“叉子”或“勺子”来“吃”更好-等于询问是否使用静态 [===] 与动态[==]eq.,同前。在JS中。这两个问题同样是错误的,反映了对所讨论主题的非常狭窄或肤浅的理解。