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
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**
而这只是你用原语获得的疯狂东西 .
当你使用 == 对象时,这是一个全新的疯狂程度 .
此时你可能想知道......
Why does this happen?
嗯,这是因为与"triple equals"( === )不同,它只是检查两个值是否相同 .
== 做 whole bunch of other stuff .
它具有对函数的特殊处理,对空值的特殊处理,未定义,字符串,您可以对其进行命名 .
这很古怪 .
事实上,如果你试图编写一个能够执行 == 操作的函数,它将看起来像这样:
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();
}
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
123=='123' //will return true, because JS convert integer 123 to string '123'
//as we used '==' operator
123==='123' //will return false, because JS do not convert integer 123 to string
//'123' as we used '===' operator
29
=== 运算符称为严格比较运算符, does 与 == 运算符不同 .
让我们采取2个变量a和b .
要 "a == b" 评估为真,a和b需要为 same value .
在 "a === b" 的情况下,a和b必须是 same value 并且 same type 才能评估为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");
}
In summary ;使用 == 运算符可能会在您不希望它的情况下评估为true,因此使用 === 运算符会更安全 .
在90%的使用场景中,使用哪一个并不重要,但是当你有一天意外行为时,知道差异就很方便了 .
78
问题是你很容易遇到麻烦,因为JavaScript有很多隐含的转换意味着......
var x = 0;
var isTrue = x == null;
var isFalse = x === null;
'' == 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.
22
一个简单的例子是
2 == '2' -> true, values are SAME because of type conversion.
2 === '2' -> false, values are NOT SAME because of no type conversion.
35
这意味着 equality without type coercion 类型强制意味着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
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
这是因为 equality operator == does type coercion ,意味着解释器在比较之前隐式尝试转换值 .
另一方面, identity operator === does not do type coercion ,因此在比较时不会转换值 .
89
在这里的答案中,我没有读到关于 equal 的含义的任何内容 . 有些人会说 === 意味着 equal and of the same type ,但事实并非如此 . 它实际上意味着 both operands reference the same object ,或者在 value types, have the same value 的情况下 .
那么,我们来看下面的代码:
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
这种行为并不总是很明显 . 故事不仅仅是平等而且属于同一类型 .
规则是:
For value types (numbers): 如果 a 和 b 具有相同的值并且属于同一类型, a === b 将返回true
For reference types: 如果 a 和 b 引用完全相同的对象, a === b 将返回true
For strings: 如果 a 和 b 都是字符串并且包含完全相同的字符, a === b 将返回true
30 回答
在典型的脚本中,没有性能差异 . 更重要的是,千"==="比千字节重1 KB "==" :) JavaScript profilers可以告诉你,如果你的情况有性能差异 .
但就我个人而言,我会做JSLint所说的 . 这个建议不是因为性能问题,而是因为类型强制意味着
('\t\r\n' == 0)
是真的 .标识(
===
)运算符与相等(==
)运算符的行为相同,但不进行类型转换,并且类型必须相同才能被视为相等 .参考:Javascript Tutorial: Comparison Operators
在执行任何必要的类型转换后,
==
运算符将比较相等性 .===
运算符将 not 进行转换,因此如果两个值不是同一类型===
将只返回false
. 两者都同样快 .引用Douglas Crockford的优秀JavaScript: The Good Parts,
false =='false'// false
false =='0'//是的
false == undefined // false
false == null // false
null == undefined // true
'\ t \ r \ n'== 0 //是的
缺乏传递性令人震惊 . 我的建议是永远不要使用邪恶的双胞胎 . 相反,始终使用===和!== . 刚显示的所有比较都与===运算符产生错误 .
更新:
@Casebash在评论和@Phillipe Laybaert's answer中提到了关于参考类型的一个好点 . 对于参考类型
==
和===
彼此一致地行动(特殊情况除外) .特殊情况是,当您将文字与评估为同一文字的对象进行比较时,由于其
toString
或valueOf
方法 . 例如,考虑字符串文字与字符串的比较由String
构造函数创建的对象 .这里
==
运算符正在检查两个对象的值并返回true
,但===
看到它们不是同一类型并返回false
. 哪一个是正确的?这实际上取决于你String
使用String
构造函数来创建字符串对象 .Reference
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
它检查 type 中的相同边是否相等以及 value .
示例:
常见例子:
另一个常见的例子:
Yes! 这很重要 .
===
运算符在javascript checks value as well as type 中==
运算符只检查 the value (does type conversion if required) .你可以轻松测试它 . 将以下代码粘贴到HTML文件中,然后在浏览器中打开它
您将在警报中获得“ false ” . 现在将
onPageLoad()
方法修改为alert(x == 5);
,您将获得 true .null和undefined是虚无,也就是说,
这里
a
和b
没有值 . 然而,0,false和''都是值 . 所有这些之间的共同点是它们都是虚假的 Value 观,这意味着它们都是错误的条件 .因此,0,false和''一起形成一个子组 . 另一方面,null和undefined形成第二个子组 . 检查下图中的比较 . null和undefined会相等 . 其他三个将彼此相等 . 但是,它们都被视为JavaScript中的虚假条件 .
这与任何对象(如{},数组等)相同,非空字符串和布尔值都是真实的条件 . 但是,他们都不平等 .
===
运算符检查值以及变量的类型是否相等 .==
运算符只是检查变量的值是否相等 .前两个答案都提到==表示平等,===表示身份 . 不幸的是,这种说法不正确 .
如果==的两个操作数都是对象,则比较它们以查看它们是否是同一个对象 . 如果两个操作数都指向同一个对象,则等于运算符返回true . 否则,两者并不相等 .
在上面的代码中,==和===都得到false,因为a和b不是同一个对象 .
也就是说:如果==的两个操作数都是对象,==的行为与===相同,这也意味着身份 . 这两个运算符的本质区别在于类型转换 . ==在检查相等性之前进行转换,但===没有 .
我使用Firebug在Firefox中测试了这个,使用如下代码:
和
我的结果(每次测试五次并取平均值):
所以我要说微不足道的差异(这是超过100000次迭代,记得)可以忽略不计 . 表现 isn't 做
===
的原因 . 键入安全性(嗯,安全性与JavaScript相同),代码质量也是如此 .Why == is so unpredictable?
将空字符串
""
与数字零0
进行比较时,您会得到什么?true
是的,根据
==
是一个空字符串,数字零是同一时间 .它并没有结束,这是另一个:
Things get really weird with arrays.
Then weirder with strings
情况变得更糟:
When is equal not equal?
让我再说一遍:
而这只是你用原语获得的疯狂东西 .
当你使用
==
对象时,这是一个全新的疯狂程度 .此时你可能想知道......
Why does this happen?
嗯,这是因为与"triple equals"(
===
)不同,它只是检查两个值是否相同 .==
做 whole bunch of other stuff .它具有对函数的特殊处理,对空值的特殊处理,未定义,字符串,您可以对其进行命名 .
这很古怪 .
事实上,如果你试图编写一个能够执行
==
操作的函数,它将看起来像这样:So what does this mean?
这意味着
==
很复杂 .因为它很复杂,所以很难知道当你使用它时会发生什么 .
这意味着你最终可能会遇到错误 .
So the moral of the story is...
让你的生活变得简单 .
使用
===
而不是==
.结束 .
来自core javascript reference
Javascript执行流程图,用于严格相等/比较'==='
用于非严格相等/比较的Javascript执行流程图'=='
JavaScript
===
vs==
.在PHP和JavaScript中,它是一个严格的相等运算符 . 这意味着,它将比较类型和值 .
根据经验,我通常会使用
===
而不是==
(和!==
而不是!=
) .原因在上面的答案中解释,道格拉斯克罗克福德也非常清楚(JavaScript: The Good Parts) .
但是有 one single exception :
== null
是检查'is null or undefined'的有效方法:例如,jQuery 1.9.1使用此模式43次,因此JSHint syntax checker甚至提供
eqnull
放松选项 .来自jQuery style guide:
让我补充一下这个忠告:
If in doubt, read the specification!
ECMA-262是脚本语言的规范,JavaScript是一种方言 . 当然,在实践中,最重要的浏览器的行为方式比关于如何处理某些内容的深奥定义更重要 . 但是理解为什么 new String("a") !== "a" 是有帮助的 .
请让我解释如何阅读说明书以澄清这个问题 . 我看到在这个非常古老的话题中,没有人能够得到非常奇怪的效果的答案 . 因此,如果您能阅读规范,这将极大地帮助您完成您的职业 . 这是一项后天的技能 . 那么,让我们继续吧 .
在PDF文件中搜索===,将我带到规范的第56页: 11.9.4. The Strict Equals Operator ( === ) ,在浏览规范后,我发现:
有趣的是第11步 . 是的,字符串被视为值类型 . 但这并不能解释为什么 new String("a") !== "a" . 我们的浏览器是否符合ECMA-262标准?
没那么快!
我们来检查一下操作数的类型 . 通过将它们包装在_92577中来亲自尝试一下 . 我发现 new String("a") 是一个对象,并且使用了第1步:如果类型不同,则返回 false .
如果你想知道为什么 new String("a") 没有返回一个字符串,那么阅读规范的练习怎么样?玩得开心!
Aidiakapi在下面的评论中写道:
new 总是返回一个Object,即使对于 String 构造函数也是如此 . 唉!字符串的值语义(参见步骤11)将丢失 .
这最终意味着: new String("a") !== "a" .
在JavaScript中,它意味着相同的值和类型 .
例如,
但
只是
==
表示操作数之间 comparison withtype conversion
&
===
表示操作数之间 comparison withouttype conversion
javaScript中的类型转换意味着javaScript会自动将任何其他数据类型转换为字符串数据类型 .
例如:
=== 运算符称为严格比较运算符, does 与 == 运算符不同 .
让我们采取2个变量a和b .
要 "a == b" 评估为真,a和b需要为 same value .
在 "a === b" 的情况下,a和b必须是 same value 并且 same type 才能评估为true .
以下面的例子为例
In summary ;使用 == 运算符可能会在您不希望它的情况下评估为true,因此使用 === 运算符会更安全 .
在90%的使用场景中,使用哪一个并不重要,但是当你有一天意外行为时,知道差异就很方便了 .
问题是你很容易遇到麻烦,因为JavaScript有很多隐含的转换意味着......
这很快就会成为一个问题 . 隐式转换为"evil"的最佳样本可以从MFC / C中的这段代码中获取,由于从CString到HANDLE的隐式转换,它实际上将被编译,这是一个指针typedef类型...
显然在运行时期间有很多未定义的东西......
Google在C和STL中进行隐式转换,以获得一些反对它的论据......
The equal comparison operator == is confusing and should be avoided.
如果你 HAVE TO 与它一起生活,那么请记住以下三件事:
It is not transitive: (a == b) and (b == c) does not lead to (a == c)
It's mutually exclusive to its negation: (a == b) and (a != b) always hold opposite Boolean values, with all a and b.
In case of doubt, learn by heart the following truth table:
JAVASCRIPT中的等号运算符真值表
** STRANGE:请注意,第一列中的任何两个值在这个意义上都不相等 . **
一个简单的例子是
这意味着 equality without type coercion 类型强制意味着JavaScript不会自动将任何其他数据类型转换为字符串数据类型
在您的使用中,这两个操作之间不可能有任何性能差异 . 没有要进行类型转换,因为两个参数已经是同一类型 . 两个操作都将进行类型比较,然后进行值比较 .
这是一项严格的检查测试 .
这是一件好事,尤其是如果您在0和false之间进行检查并且为null .
例如,如果您有:
然后:
所有都返回true,你可能不想要这个 . 假设您有一个函数可以返回数组的第0个索引,或者在失败时返回false . 如果您使用“==”false检查,则可能会产生令人困惑的结果 .
所以与上面相同,但严格的测试:
使用
==
运算符(Equality)使用
===
运算符(标识)这是因为 equality operator == does type coercion ,意味着解释器在比较之前隐式尝试转换值 .
另一方面, identity operator === does not do type coercion ,因此在比较时不会转换值 .
在这里的答案中,我没有读到关于 equal 的含义的任何内容 . 有些人会说
===
意味着 equal and of the same type ,但事实并非如此 . 它实际上意味着 both operands reference the same object ,或者在 value types, have the same value 的情况下 .那么,我们来看下面的代码:
和这里一样:
甚至:
这种行为并不总是很明显 . 故事不仅仅是平等而且属于同一类型 .
规则是:
For value types (numbers):
如果
a
和b
具有相同的值并且属于同一类型,a === b
将返回trueFor reference types:
如果
a
和b
引用完全相同的对象,a === b
将返回trueFor strings:
如果
a
和b
都是字符串并且包含完全相同的字符,a === b
将返回true字符串:特例......
字符串不是值类型,但在Javascript中它们的行为类似于值类型,因此它们将是“相等”的字符串中的字符是相同的,当它们具有相同的长度时(如第三条规则中所述)
现在它变得有趣:
但是怎么样?:
我认为字符串的行为类似于值类型?嗯,这取决于你问谁...在这种情况下,a和b不是同一类型 .
a
的类型为Object
,而b
的类型为string
. 请记住,使用String
构造函数创建一个字符串对象会创建Object
类型的东西,它在大多数情况下都表现为字符串 .JSLint有时会给你修改内容的不切实际的理由 . 如果类型已经相同,
===
与==
具有完全相同的性能 .仅当类型不相同时才更快,在这种情况下它不会尝试转换类型但直接返回false .
因此,恕我直言,JSLint可能用于编写新代码,但应该不惜一切代价避免无用的过度优化 .
意思是,没有理由在
if (a == 'test')
之类的支票中将==
更改为===
,当你知道它只能是一个字符串时 .修改大量代码会浪费开发人员和审阅者的时间并且什么都不会实现 .
==
和===
之间相等比较的有趣图形表示 .Source: http://dorey.github.io/JavaScript-Equality-Table/
var1 === var2
var1 == var2
Equality comparison:
运营商
==
当两个操作数相等时返回true . 在比较之前,操作数被转换为相同的类型 .
Equality and type comparison:
运营商
===
如果两个操作数相等且类型相同,则返回true . 如果你比较这种方式通常会更好更安全,因为没有幕后类型的转换 .