首页 文章

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

提问于
浏览
5673

我正在使用JSLint来通过JavaScript,它正在返回许多建议,用 === (三个等号)替换 == (两个等号),比如在 if 语句中比较 idSele_UNVEHtype.value.length == 0 .

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

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

如果没有进行类型转换,那么性能是否会超过 ==

30 回答

  • 23

    在典型的脚本中,没有性能差异 . 更重要的是,千"==="比千字节重1 KB "==" :) JavaScript profilers可以告诉你,如果你的情况有性能差异 .

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

  • 575

    标识( === )运算符与相等( == )运算符的行为相同,但不进行类型转换,并且类型必须相同才能被视为相等 .

    参考:Javascript Tutorial: Comparison Operators

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

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

    JavaScript有两组相等运算符:===和!==,它们的邪恶双胞胎==和!= . 优秀的工作方式与您期望的方式相同 . 如果两个操作数具有相同的类型且具有相同的值,则===生成true,并且!==生成false . 当操作数属于同一类型时,邪恶的双胞胎做正确的事,但如果它们属于不同的类型,它们会试图强迫 Value 观 . 他们这样做的规则是复杂和不可取的 . 这些是一些有趣的案例:''=='0'// false
    0 ==''//是的
    0 =='0'//是的

    false =='false'// false
    false =='0'//是的

    false == undefined // false
    false == null // false
    null == undefined // true

    '\ t \ r \ n'== 0 //是的
    缺乏传递性令人震惊 . 我的建议是永远不要使用邪恶的双胞胎 . 相反,始终使用===和!== . 刚显示的所有比较都与===运算符产生错误 .


    更新:

    @Casebash在评论和@Phillipe Laybaert's answer中提到了关于参考类型的一个好点 . 对于参考类型 ===== 彼此一致地行动(特殊情况除外) .

    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 使用 String 构造函数来创建字符串对象 .

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

  • 18

    它检查 type 中的相同边是否相等以及 value .

    示例:

    '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
    
  • 1029

    Yes! 这很重要 .

    === 运算符在javascript checks value as well as type== 运算符只检查 the value (does type conversion if required) .

    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); ,您将获得 true .

  • 5911

    null和undefined是虚无,也就是说,

    var a;
    var b = null;
    

    这里 ab 没有值 . 然而,0,false和''都是值 . 所有这些之间的共同点是它们都是虚假的 Value 观,这意味着它们都是错误的条件 .

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

    Enter image description here

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

  • 46

    === 运算符检查值以及变量的类型是否相等 .

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

  • 71

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

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

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

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

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

  • 64

    我使用Firebug在Firefox中测试了这个,使用如下代码:

    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次迭代,记得)可以忽略不计 . 表现 isn't=== 的原因 . 键入安全性(嗯,安全性与JavaScript相同),代码质量也是如此 .

  • 256

    Why == is so unpredictable?

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

    true

    是的,根据 == 是一个空字符串,数字零是同一时间 .

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

    '0' == false // true
    

    Things get really weird with arrays.

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

    Then weirder with strings

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

    情况变得更糟:

    When is equal not equal?

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

    So what does this mean?

    这意味着 == 很复杂 .

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

    这意味着你最终可能会遇到错误 .

    So the moral of the story is...

    让你的生活变得简单 .

    使用 === 而不是 == .

    结束 .

  • 22

    来自core javascript reference

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

  • 25
    • **Operators === vs == ***
    1 == true    =>    true
    true == true    =>    true
    1 === true    =>    false
    true === true    =>    true
    
  • 35

    Javascript执行流程图,用于严格相等/比较'==='

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

  • 28

    JavaScript === vs == .

    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
    
  • 96

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

  • 30

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

    原因在上面的答案中解释,道格拉斯克罗克福德也非常清楚(JavaScript: The Good Parts) .

    但是有 one single exception== null 是检查'is null or undefined'的有效方法:

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

    例如,jQuery 1.9.1使用此模式43次,因此JSHint syntax checker甚至提供 eqnull 放松选项 .

    来自jQuery style guide

    应使用严格的等式检查(===)以支持== . 唯一的例外是通过null检查undefined和null . //由于某些重要原因,检查未定义和空值 .
    undefOrNull == null;

  • 20

    让我补充一下这个忠告:

    If in doubt, read the specification!

    ECMA-262是脚本语言的规范,JavaScript是一种方言 . 当然,在实践中,最重要的浏览器的行为方式比关于如何处理某些内容的深奥定义更重要 . 但是理解为什么 new String("a") !== "a" 是有帮助的 .

    请让我解释如何阅读说明书以澄清这个问题 . 我看到在这个非常古老的话题中,没有人能够得到非常奇怪的效果的答案 . 因此,如果您能阅读规范,这将极大地帮助您完成您的职业 . 这是一项后天的技能 . 那么,让我们继续吧 .

    在PDF文件中搜索===,将我带到规范的第56页: 11.9.4. The Strict Equals Operator ( === ) ,在浏览规范后,我发现:

    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 . 13.如果x和y引用同一个对象或它们引用相互连接的对象,则返回true(见13.1.2) . 否则,返回false .

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

    没那么快!

    我们来检查一下操作数的类型 . 通过将它们包装在_92577中来亲自尝试一下 . 我发现 new String("a") 是一个对象,并且使用了第1步:如果类型不同,则返回 false .

    如果你想知道为什么 new String("a") 没有返回一个字符串,那么阅读规范的练习怎么样?玩得开心!


    Aidiakapi在下面的评论中写道:

    来自规范11.2.2新运算符:如果Type(构造函数)不是Object,则抛出TypeError异常 . 换句话说,如果String不是Object类型,则它不能与new运算符一起使用 .

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

    这最终意味着: new String("a") !== "a" .

  • 18

    在JavaScript中,它意味着相同的值和类型 .

    例如,

    4 == "4" // will return true
    

    4 === "4" // will return false
    
  • 32

    只是

    == 表示操作数之间 comparison with type conversion

    === 表示操作数之间 comparison without 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
    
  • 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;
    

    这很快就会成为一个问题 . 隐式转换为"evil"的最佳样本可以从MFC / C中的这段代码中获取,由于从CString到HANDLE的隐式转换,它实际上将被编译,这是一个指针typedef类型...

    CString x;
    delete x;
    

    显然在运行时期间有很多未定义的东西......

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

  • 52

    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中的等号运算符真值表

    • 表中的每一行都是一组3个相互"equal"的值,这意味着它们之间的任何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.
    
  • 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
    
  • 42

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

  • 570

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

    这是一件好事,尤其是如果您在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
    
  • 92

    使用 == 运算符(Equality)

    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):
    如果 ab 具有相同的值并且属于同一类型, a === b 将返回true

    For reference types:
    如果 ab 引用完全相同的对象, a === b 将返回true

    For strings:
    如果 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 类型的东西,它在大多数情况下都表现为字符串 .

  • 21

    JSLint有时会给你修改内容的不切实际的理由 . 如果类型已经相同, ===== 具有完全相同的性能 .

    仅当类型不相同时才更快,在这种情况下它不会尝试转换类型但直接返回false .

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

    意思是,没有理由在 if (a == 'test') 之类的支票中将 == 更改为 === ,当你知道它只能是一个字符串时 .

    修改大量代码会浪费开发人员和审阅者的时间并且什么都不会实现 .

  • 51

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

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


    var1 === var2

    当使用===进行JavaScript相等测试时,一切都按原样 . 在评估之前没有任何东西被转换 .

    Equality evaluation of === in JS


    var1 == var2

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

    Equality evaluation of == in JS

    故事的道德:除非您完全理解使用==进行的转换,否则请使用=== .

  • 69

    Equality comparison:

    运营商 ==

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

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

    Equality and type comparison:

    运营商 ===

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

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

相关问题