在JavaScript中何时使用==是正确的?

转载:http://www.cnblogs.com/yanhaijing/p/3685290.htmlhtml

JavaScript中什么状况下使用==是正确的?简而言之:没有。这篇文章来看五种状况下老是使用===,而且解释为何不用==。浏览器

JavaScript有两种操做符用来比较两个值是否相等 [1]服务器

  • 严格相等 === 仅考虑相同类型的值是否相等。
  • “正常”(或非严格)相等操做符 == 在比较以前,尝试为不一样类型的值进行转换,而后相似严格相等。

给JavaScript初学者的建议是彻底忘掉 == ,而且老是使用 ===。事实证实,后者是更符合常规的。有五种案例,表面看起来能够不听从规则,但真的不是这样。从如今开始,我使用下面的规则:函数

意图清晰的代码赛过更简洁的代码。

记住:你的代码仅写一次,但被阅读不少次——尽量保证对阅读者友好。性能

例1:你清楚本身在比较什么

例如,使用typeof操做符[2],你能确保结果是字符串。而后能够放心使用 ==,由于咱们肯定不会在发生类型转换。学习

if (typeof x == "function") {
        ...
}

然而,有两个反对这样作的缘由:编码

  • 一致性:使用==对一致性没有任何好处,那么为何不避免使用呢?
  • 简单和性能:通常来讲,=== 是最简单的操做符,由于它不进行类型转换。JavaScript引擎的性能良莠不齐[3],但在大部分浏览器中 === 比 == 速度更快。

例2:与undefined和null作比较

当使用 == 时,undefined和null在结果上等价——他们彼此相等,互相相等,但没有意义(包括JavaScript中的能被转换为false的值):spa

复制代码
    > null == null
    true
    > undefined == null
    true
    > false == null
    false
    > 0 == null
    false
复制代码

所以,下面的if语句检测的是null或undefined。code

    if (x == null) {
        ...
    }

然而,这是否出于简洁性考虑,意图并不清晰:若是你同时也检测undefined,那么你能够这样写。然而,若是JavaScript初学者读到你的代码,他们可能认为你仅仅检测null。若是高手读到你的代码,他们可能认为你写错了,而且应该写成 ===。htm

    if (x === undefined || x === null) {
        ...
    }

若是你有点懒的话,上面的代码能被精简为:

    if (!x) {
        ...
    }

和上面同样的警告:这条件成立,若是x有否认类型的值。

    undefined
    null
    false
    0
    ""

例3:比较字符串和数字

场景:你正工做在用户界面代码或编码处理服务器端参数。你可能会把数字编码为字符串。若是x是一个字符串,你能够像下面这样比较:

    if (x == 123) {
        ...
    }

但问什么不告诉其余阅读你代码的人,若是x不是数字,它将被转换为数字?

    if (Number(x) === 123) {
        ...
    }

例4:比较对象和原始值

使用 == 时你能够将一个原始值和其余原始值或包装类型 [4]实例作比较:

    > function isAbc(x) { return x == "abc" }
    > isAbc("abc")
    true
    > isAbc(new String("abc"))
    true

而使用 === 时,你不能这样作:

    > new String("abc") === "abc"
    false

 左边是一个对象而右边是原始值。由于他们类型不一样因此不严格相等。然而,你一样须要向阅读你代码的人解释清楚你的意图。下面是表达式:

 x == "abc"

你的目的是什么?

  • 你真的想让一个包装字符串和右边的字符串做比较吗?这彷佛不太可能,但若是确实是这样,你应该当心翼翼并给出文档记录。
  • 你想将x转换为字符串?那应该写的更明确
    String(x) === "abc"
  • 你想提取包装变量的原始值?那你应该考虑下面的写法
     x.valueOf() === "abc"

例5:JavaScript是灵活的语言——个人代码也应该这样

理由是这样的:我想个人代码像JavaScript同样灵活。== 操做符帮我实现这一目的。例如JavaScript的灵活体如今它自动转换值类型:

    > "abc" + false
    'abcfalse'
    > 3 + true
    4
    > +"73"
    73

有几个理由反驳上述假说:

  • 即便会自动转换但并不老是按你须要的方式转换。例如:
  • 复制代码
        > !"false"
        false
        > 7 + "3"
        '73'
        > Number("")
        0
    复制代码
  • 非严格相等的转换规则很是复杂:
        > 2 == false
        false
        > 2 == true
        false
        > Boolean(2)
        true
  • 显示转化加上严格相等的代码更具描述性。比较:灵活的非严格相等。
    复制代码
    function is123Implicit(x) {
            return x == 123;
        }
        > is123Implicit(123)
        true
        > is123Implicit(new Number(123))
        true
        > is123Implicit("123")
        true
    复制代码
    替代方案:灵活的显式转换和严格相等。
    复制代码
    function is123Explicit(x) {
            x = Number(x);
            return x === 123;
        }
        > is123Explicit(123)
        true
        > is123Explicit(new Number(123))
        true
        > is123Explicit("123")
        true
    复制代码

     

  • 有人说您的代码缺乏灵活性?能够说JavaScript的默认灵活性利大于弊(对于学习难度而言)。写防护型的代码更容易暴漏Bug。is123Explicit() 的防护型版本看起来像下面这样:
    function is123Defensive(x) {
            if (typeof x !== "number") {
                throw new TypeError("Not a number: "+x);
            }
            return x === 123;
        }
    若是你想给函数传递任何非原始数字值,你必须先进行类型转换。
相关文章
相关标签/搜索