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


5665

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

有没有性能优势,以代替=====

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

如果没有进行类型转换,那么性能会提高==吗?


134
谁可能是感兴趣的同一主题=== vs ==,但在PHP中,可以在这里阅读:stackoverflow.com/questions/2401478/why-is-faster-than-in-php/...
马尔科Demaio

257
万一有人在2012年想知道:===这样的速度比==jsperf.com/comparison-of-comparisons
Ry-

25
@minitech它应该是因为它不执行类型转换
UmurKontacı2012年

19
@minitech,我怀疑有人通过使用===over可以显着提高其应用程序的速度==。实际上,基准测试在现代浏览器上并没有显示出很大的差异。就个人而言,==除非确实需要严格的平等性,否则我通常会在任何地方使用。
劳伦特

5
这是Crockford的JS The Good Parts演讲的一部分,他在其中讨论了===and ==运算符:youtube.com/…如果没有播放,则在15:20
davidhiggins 2013年

Answers:


6482

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

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

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

引用Douglas Crockford出色的JavaScript:The Good Parts

JavaScript有两套相等运算符:===!==,以及它们的邪恶孪生子==!=。优秀的产品以您期望的方式工作。如果两个操作数具有相同的类型并具有相同的值,则===产生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

平等比较表

传递性的缺乏令人震惊。我的建议是不要使用邪恶的双胞胎。相反,请始终使用===!==。刚刚显示的所有比较都是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

特殊情况是,当您比较一个基元和一个对象时,由于该对象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


236
如果类型相同,则===不会更快。如果类型不同,则===会更快,因为它不会尝试进行转换。
比尔蜥蜴

520
===永远不会比==慢。它们都进行类型检查,因此===与==相比并没有做任何其他事情,但是当类型不同时,类型检查可能允许===更快地退出。
比尔蜥蜴

246
用=== /!==替换所有== /!=会增加js文件的大小,这将花费更多时间来加载。:)
Marco Demaio 2010年

92
“ ...这些规则复杂而令人难忘...”现在,这样的语句使您在编程时感到如此安全……
Johan

47
克罗克福德(Crockford)表示:“缺乏传递性令人震惊。” 如果您开发软件并且在比较运算符警告中没有发现传递性不足,或者如果您认为==和===之间的速度比较或文件大小/加载时间优先于比较运算符行为的传递确定性,可能需要返回并重新开始。
jinglesthula 2014年

1144

使用==运算符(等于

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

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

另一方面,身份运算符===不会执行强制类型转换,因此在比较时不会转换值,因此跳过一个步骤会更快(根据This JS基准测试)。


9
@Software Monkey:不适用于值类型(数字,布尔值,...)
Philippe Leybaert 2009年

33
由于没有人提到的Javascript平等表,那就是:dorey.github.io/JavaScript-Equality-Table
杀出

6
在第一条语句中,您确定将“ true”转换为1而不是将1转换为true吗?
Shadi Namrouti

2
术语“平等”和“身份”从何而来?该标准不使用这些术语。它称为==“抽象平等”,又称为===“严格平等”。诚然调用==任何形式的“平等”是恕我直言可怕的,因为它是不可传递的,但为什么狡辩?我对“身份”有更多的问题;我认为这个词虽然“有效”,但却颇具误导性。但是说真的,谁创造了“身份”一词?我搜索了标准,但找不到它。
Ray Toal

1
“身份”是非常错误的词。在所有我使用的语言身份比较方法在同一个对象,即两个引用变量指向不只是相当于实体,但同一个实体。
Inigo

722

==和之间的相等比较的有趣的图形表示形式===

资料来源:http : //dorey.github.io/JavaScript-Equality-Table/


var1 === var2

===用于JavaScript相等性测试时,一切保持原样。在评估之前,没有任何转换。

JS中===的相等性评估


var1 == var2

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

JS中==的相等性评估

故事的道德启示:

使用===除非你完全明白发生与转换==


3
@mfeine是指===或!==而不是==或!=。不想混淆新的编码器;)
katalin_2003

2
根据我的经验,使用三个等号可能会导致问题,除非完全理解,否则应避免使用。两个等于会产生更好的结果,因为99%的时间我确实不希望类型相等。
vsync

12
@vsync:如果您真的不希望类型相等则应使用三个equals
SNag

6
唯一的例外:您可以放心地x == null检查xis nullundefined
安迪

1
@ user648026:问题是关于与vs的相等比较。无论如何,大写和小写是不相等的,并且将与和运算符一起返回。另外,关键字,,,,存在于JS仅在一个情况下,不能在上部或混合的情况下使用。=====false=====truefalseundefinednullInfinity
SNag

609

在这里的答案中,我什么都没有读到什么相等的意思。有人会说这===意味着相等且属于同一类型,但这不是真的。实际上,意味着两个操作数都引用相同的对象,或者在值类型的情况下,它们具有相同的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

这种现象并不总是很明显。故事不只是平等和同类型。

规则是:

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

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

对于字符串:
a === b如果ab均为字符串且包含完全相同的字符,则返回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是类型的Objectb而是类型的string。只需记住,使用String构造函数创建字符串对象会创建某种类型的东西,大多数情况下,Object它们的行为类似于字符串。


6
激活:我要澄清的是,只有当字符串是文字时,字符串才如此相等。new String(“ abc”)===“ abc”为假(根据我的研究)。
劳伦斯·多尔

3
new Number() == "0"。也在Firefox中:(function(){}) == "function () {\n}"
Thomas Eding

3
谢谢您解释原因new String("123") !== "123"。它们是不同的类型。简单,但令人困惑。
styfle

21
String对象的行为与其他对象的行为一样。new String永远不要使用,因为那不会创建真实的字符串。真正的字符串,可以用字符串文字或不带String的函数调用而制成,例如: newString(0); //"0", Real string, not an object
Esailija 2012年

6
但是在您详细说明的情况下,运算符“ ==”的行为完全相同。
亚伦·列维

270

让我补充一下这个建议:

如有疑问,请阅读规格

ECMA-262是JavaScript语言为方言的脚本语言规范。当然,实际上,最重要的浏览器的行为方式远比对应该如何处理某些事物的神秘定义更为重要。但是了解为什么新的String(“ a”)!==“ a”很有帮助。

请让我解释如何阅读规范以阐明此问题。我看到,在这个非常老的话题中,没有人对非常奇怪的结果有任何答案。因此,如果您可以阅读规范,这将对您的职业产生极大的帮助。这是一项后天的技能。因此,让我们继续。

在PDF文件中搜索===使我进入规范的第56页:11.9.4。Strict Equals运算符(===),在仔细研究了规范性语言后,我发现:

11.9.6严格相等比较算法
比较x === y(其中x和y是值)产生truefalse。这样的比较执行如下:
  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;否则,返回true。否则,返回false
  12.如果Type(x)为布尔值,则如果x和y均为true或均为false,则返回true;否则,返回false。   13.返回true
如果x和y指的是同一个对象,或者它们是指相互连接的对象(请参见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运算符一起使用。

即使对于String构造函数,new也会始终返回Object 。a!字符串的值语义(请参见步骤11)丢失。

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


Type(x)的结果暗示与typeof?相同。
Dfr

@nalply我并不完全了解with的行为焦虑new String('x'),因为我从来没有见过任何使用原始包装对象的代码,而且我认为没有充分的理由,尤其是最近没有。您是否曾经遇到过这样做的代码?
安迪

@Andy这个问题是恶意的,或者只是草率的第三方代码,因此您不能假定没有人使用new String()
nalply

如果太草率,===是您会发现的方式。如果是恶意的,我认为new String()这可能是您最少的担心。我理解理论上的担忧,但是,您又有一些真实的例子吗?对我而言,就像有人可能将undefined另一个价值观设定为旧的焦虑一样。
安迪

我不知道您从哪里得到的,但是您的比较算法在第2步出错。“ 7.2.15严格相等比较”部分首先检查类型是否相同,如果是,则它们是否为Number。如果不是,则使用“ 7.2.12 SameValueNonNumber(x,y)”部分。
Rusty Core

101

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


10
@David:对。这就是为什么这个答案是不正确的(甚至是错误的)
菲利普Leybaert

7
@David var a = {}, b = {}; a == b返回false。
nyuszika7h 2011年

6
是:具有相同类型和值的两个不同对象比较为假,即,此答案是错误的。为什么会有50个投票?
Alexis

4
我意识到这很古老,但是要弄清楚为什么这个答案仍然是“正确的”,是因为在示例中,var a = {}, b = {};虽然ab确实都是对象,但从技术上讲,它们的值并不相同。它们是不同的实例。请注意,比较实例的行为与比较基元的行为不同。这可能会增加这种混乱。如果使用原始数据类型的实例版本,您将看到类似的比较行为。例如new String('asdf')new Number(5)。例如:new Number(5) == new Number(5)即使它们具有相同的值,它也是错误的。
诺曼·布鲁

1
我们都忘记了对对象的引用实际上是一个值类型,因为它是指向内存插槽的指针。对象比较不是在比较“对象的值”,而是两个指针是否相同,这意味着它们引用相同的内存插槽。比较类型时,这是一个非常微妙的区别,因为“ ===”运算符确实需要说“如果类型,值和对内存中对象的引用相同”。
斯托克利

101

我使用以下代码在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中一样安全),代码质量也是如此。


3
除了类型安全性之外,您还需要逻辑上的正确性-有时,您希望事情在==不同意时成为事实。
rpjohnst 2011年

4
现在,当==操作员有实际的类型强制时,这些如何比较?请记住,那是性能提升的时候。
休伯特·奥格

2
由于前面提到的原因而进行正确测试时,主要差异在于更快地检查类型不平等。jsfiddle.net/4jhuxkb2
Doug Morrow

您可以使用console.time()来度量每秒操作的性能,而不是使用console.time()在单个浏览器(具有约5%的市场份额)中进行单个测试,同时使用不带类型强制性的测试(整个原因)较慢)。这是一个完全没有意义的测试。您是正确的,因为性能不是使用===过度的理由,==但您错了,他们的性能基本相同,并且您认为此测试证明了这一点,并且得到许多其他人的同意,这对我来说是完全荒谬的,这是错误的。
Stephen M Irving

96

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

例如,

4 == "4" // will return true

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

87

===运算符称为严格的比较操作符,它不会从不同的==操作符。

让我们取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%的使用情况下,使用哪一个都无关紧要,但是,有一天在您遇到某些意外行为时,很容易知道它们之间的区别。


82

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

将空字符串""与数字零进行比较会得到什么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**

这只是您使用基元所获得的疯狂东西。

==与对象一起使用时,这是一个全新的疯狂级别。

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

为什么会这样?

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

==还有很多其他的东西

您可以对函数进行特殊处理,对null,undefined,字符串进行特殊处理。

很古怪。

实际上,如果您试图编写一个执行该功能的函数,==它将看起来像这样:

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();
}

那么这是什么意思?

这意味着==很复杂。

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

这意味着您可能会遇到bug。

所以这个故事的寓意是

让您的生活不再那么复杂。

使用===代替==

结束。


looseEqual错了 Function == Function.toString()是正确的,但是looseEqual(Function, Function.toString())错误的。不知道为什么一开始就过滤掉功能。
Oriol

@Oriol,您说得对,我更新了代码来说明这一点,根据我的测试,FYI不足以删除“函数”的过滤器,而必须完全不同地处理“函数”。
路易斯·佩雷斯

请注意,规范并没有区别对待函数,它们只是对象。问题似乎是您依赖typeof x === "object"检查它是否是一个对象,但是`typeof仅适用于非null原语。您可能对我检查值是否为对象的正确方法列表
Oriol

我尝试将功能和对象相同,但是发现结果不正确。例如,如果将函数视为对象,则将函数与实现valueOf()或与该函数匹配的toString()函数的对象进行比较会通过,但实际上不会通过。示例:(function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}-查看运行所有测试的JS小提琴:jsfiddle.net/luisperezphd/7k6gcn6g(有1,225个测试排列)
Luis Perez

1
您是对的,很棒的观察,它强调了==要做很多事情的要点,这使得很难预期结果,而===更直接,更可预测,这是===推荐选择的主要原因之一。(我会在答案中添加注释,以提及您的观点)
路易斯·佩雷斯

81

===检查同一面在类型价值上是否相等。


例:

'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 或者""


7
同样,'string' !== 'number'
Homer

71

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

JavaScript严格平等

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

JavaScript非相等


我不明白为什么string箭头指向大的灰色框,这是否意味着中断器将字符串转换为数字?
vsync

@vsync它指向灰色框中的字符串选项,即字符串->#|| NaN。Javascript不是一种类型脚本语言,也就是说,它基本上可以具有任何类型的变量。因此,它指向该灰色框。
Samar Panda

我只是问它是否用于转换目的,因为string应该将其与类型进行比较number,所以中断器会查看应该与之比较的字符串,并相应地转换字符串?
vsync

1
灰色大框是ToNumber在给定不同类型时将返回的内容,因此,如果给定一个字符串,它将仅选择最后一个选项(并将其转换为数字)。==用途ToNumber仅在箱子string == numberboolean == anything以上(且仅在string/ boolean)。这意味着==将永远不会转换undefinednull即使它们位于灰色框中也是如此。(对于其中一个undefinednull两个或两者的任意组合,==将始终返回true。此外,值在左侧还是右侧都无所谓,==(和===)将返回相同的结果。)
user2033427,18年

55

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

54

这意味着没有类型强制的相等性 类型强制意味着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 

48

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

但是我个人会按照JSLint的建议去做。出现此建议不是因为性能问题,而是因为类型强制手段('\t\r\n' == 0)是正确的。


4
并非总是如此。使用gzip压缩时,差异几乎可以忽略不计。
Daniel X Moore

1
同意,但是一千个“ ===”也意味着一万条代码行,否则大约1kb ...;)
Jonny

如果您担心大小,则只需将所有==交换为===,然后使用包装在

46

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

如果你不得不忍受它,那么请记住以下三两件事:

  1. 它不是可传递的:(a == b)(b == c)不会导致(a == c)
  2. 它与否定是互斥的:(a == b)(a!= b)始终持有相反的布尔值,并且所有a和b都存在。
  3. 如有疑问,请认真学习以下真值表:

JAVASCRIPT中的相等运算符真值表

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

** STRANGE:请注意,第一列的任何两个值在这种意义上都不相等。**

''       == 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.

39

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


38

是! 这非常重要。

===javascript中的operator会检查值以及类型,而as ==运算符只是检查值(需要时进行类型转换)

在此处输入图片说明

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

<script>

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

</script>

</head>

<body onload='onPageLoad();'>

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



32

这是严格的检查测试。

这是一件好事,尤其是如果您要检查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
在JavaScript中,这是完全错误的,并且错误地是不完整的。0 != null。-1

31

JSLint有时会给您不切实际的理由来进行修改。===具有==与类型已经完全相同的完全相同的性能。

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

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

这意味着,没有理由改变=====像一张支票if (a == 'test')当你知道它的事实只能是一个字符串。

修改大量代码会浪费开发人员和审阅者的时间,却一无所获。


30

只是

==装置的比较操作数之间 type conversion

===表示不带操作数的比较 type conversion

javaScript中的类型转换意味着javaScript自动将任何其他数据类型转换为字符串数据类型。

例如:

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 

26

一个简单的例子是

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

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

25

上面提到的前两个答案==表示平等,===表示身份。不幸的是,这个说法是不正确的。

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

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

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

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


24

根据经验,我通常会使用===代替==(和!==代替!=)。

原因在上面的答案中进行了解释,Douglas Crockford对此也很清楚(JavaScript:The Good Parts)。

但是,只有一个例外== 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;

22

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

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

哪一个很快成为问题。隐式转换为何“邪恶”的最佳示例可以从MFC / C ++中的此代码中获取,该代码实际上将由于从CString到HANDLE的隐式转换而编译,HANDLE是指针typedef类型。

CString x;
delete x;

显然,这在运行时会执行非常不确定的事情...

Google在C ++和STL中进行隐式转换,以获取针对它的一些参数...


2
0 == null是错误的。
加勒特2014年


21

平等比较:

操作员 ==

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

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

相等和类型比较:

操作员 ===

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

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


20

null和undefined是虚无,即

var a;
var b = null;

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

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

在此处输入图片说明

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.