【问题标题】:JSLint Expected '===' and instead saw '=='JSLint 期望 '===' 而看到 '=='
【发布时间】:2011-04-13 18:01:37
【问题描述】:

最近,当我遇到此错误时,我正在通过 JSLint 运行我的一些代码。我认为这个错误的有趣之处在于它自动假定所有 == 都应该是 ===。

这真的有意义吗?我可以看到很多你不想比较类型的实例,我担心这实际上会导致问题。

“预期”一词意味着每次都应该这样做......这对我来说没有意义。

【问题讨论】:

  • 我在使用 JSLint 时也遇到了这个问题。我做了从 == 到 === 的更新,它实际上破坏了以前的工作代码。
  • 如果你的代码超过100行,就不会通过jslint,真的,不可能。
  • “破产”这个词太强了。它改变了你的代码的含义。如果你在做myVar == null 检查,是的,很大的变化。 ;^) Crockford 的论点是它使代码的含义更加精确,这很难争论。

标签: javascript jslint


【解决方案1】:

IMO,盲目使用===,而不尝试理解类型转换的工作原理没有多大意义。

关于 Equals 运算符== 的主要恐惧是,取决于比较类型的比较规则会使运算符不可传递,例如,如果:

A == B AND
B == C

并不能真正保证:

A == C

例如:

'0' == 0;   // true
 0  == '';  // true
'0' == '';  // false

当您比较相同类型的值时,Strict Equals 运算符 === 并不是真正需要的,最常见的示例:

if (typeof foo == "function") {
  //..
}

我们比较typeof 运算符的结果,它总是是一个字符串,与一个字符串字面量...

或者当您知道类型强制规则时,例如,检查某事物是否为 nullundefinedsomething:

if (foo == null) {
  // foo is null or undefined
}

// Vs. the following non-sense version:

if (foo === null || typeof foo === "undefined") {
  // foo is null or undefined
}

【讨论】:

  • 我讨厌 JSLint 的这条规则。我认为真正的问题是人们不应该以他们不理解的方式使用运算符(具有讽刺意味的是,这些人通常会盲目地将 '===' 替换为 '==')。当然,将数字 0 与各种字符串进行比较时会出现一些常见情况,但如果您要比较不相关的数据,例如 0 == 'this is a string' - 您的代码可能存在比双相等更大的问题!如果你确定你正在处理什么类型并且你知道它们是如何与 == 交互的,那么我认为你应该使用它。
  • @Jon === 运算符的重点是代码清晰。没有合理的情况使用==,因为它永远不会像身份运算符那样清晰易懂。这与您是否了解运算符无关,而是关于使用使您的代码更易于阅读且几乎不花费任何费用的运算符。唯一反对身份运算符的开发人员是独立开发人员和不以团队形式工作的人。顾名思义,就是那些代码没有经过足够多的眼睛审查的人。
  • 我发现 == null 比较几乎是必不可少的。如果您的代码经过良好测试,这个问题就变得不那么重要了。
  • 事实上,有时使用 == 是必不可少的,以便执行所需的测试。如果 foo.toString() 将以可预测的方式执行并且需要针对该输出测试纯字符串,那么编写 foo == stringToTest 比 foo.toString() === stringToTest 干净得多。
  • @Alternatex 如果重点是清晰,他们不应该让它三等分!没有初学者理解它。从其他语言中至少知道双等号。此外,there is no reasonable situation 是一个严重的错误陈述。想想(本机)Javascript 类型 NumberString。它们的存在证明了 Javascript 作者对== 有一定的用例。你真的认为new String('hi') === 'hi' 评估为false 很清楚吗?请编写一个代码 sn-p 来测试您的函数参数与 'hi' 是否接受 String 和 string 并告诉我这很清楚。
【解决方案2】:

JSLint 本质上比 Javascript 语法所允许的更具防御性。

来自 JSLint 文档:

==!= 运算符在比较之前进行类型强制。这很糟糕,因为它导致' \t\r\n' == 0 为真。这可以掩盖类型错误。

与以下任何值进行比较时,请使用 ===!== 运算符(不进行类型强制):0 '' undefined null false true

如果您只关心一个值是 truthy 还是 falsy,那么请使用缩写形式。而不是

(foo != 0)

只是说

(foo)

而不是

(foo == 0)

(!foo)

===!== 运算符是首选。

【讨论】:

  • 我必须得出结论,JSLint 的人在一个他们永远无法离开的非常高的象牙塔中工作。 Javascript 设计 用于与== 运算符一起使用。 === 是一个特例...... JSLint 试图让它看起来像使用 == 会在某种程度上是错误的......但是,试试这个:var x = 4, y = new Number(4); if (x == y) {alert('Javascript depends on == just embrace it!');}。原始类型有相应的类来替代它们(NumberString),而 Javascript 依赖于 == 运算符来使这些比较自然。
【解决方案3】:

请记住,JSLint 强制人们对好的 JavaScript 应该是什么样的想法。在实施它建议的更改时,您仍然必须使用常识。

一般来说,比较类型和值将使您的代码更安全(当类型转换没有按照您的想法进行时,您不会遇到意外行为)。

【讨论】:

  • 另外,它不能像程序员那样具有上下文智能。它只是在大多数用户被系统固有的自动类型转换绊倒的基础上工作(比如暴力 - “帮助帮助我被压制!”)
【解决方案4】:

Triple-equal 与 double-equal 不同,因为除了检查两侧是否为相同的值之外,triple-equal 还检查它们是否为相同的数据类型。

所以("4" == 4) 为真,而("4" === 4) 为假。

Triple-equal 的运行速度也稍快一些,因为 JavaScript 在给出答案之前不必浪费时间进行任何类型转换。

JSLint 旨在使您的 JavaScript 代码尽可能严格,以减少晦涩难懂的错误。它强调了这类事情,试图让你以一种迫使你尊重数据类型的方式编写代码。

但是 JSLint 的好处在于它只是一个指南。正如他们在网站上所说,即使你是一个非常优秀的 JavaScript 程序员,它也会伤害你的感情。但你不应该觉得有义务听从它的建议。如果您已经阅读了它的内容并且理解了它,但您确信您的代码不会出错,那么您就不会强迫您更改任何内容。

如果您不想被警告轰炸,您甚至可以告诉 JSLint 忽略检查类别,而您不会对此采取任何行动。

【讨论】:

  • 我没有问“什么是===”,所以我不知道你为什么回答它。
  • @Metropolis:如果没有其他原因,那么作为背景,以防其他人阅读不知道的答案。不过,我确实尝试在之后的段落中回答你的问题。
  • @Spudley + 1 获取更多有用信息
  • 是的,它快了 10-100 倍:jsperf speed test
【解决方案5】:

引用http://javascript.crockford.com/code.html:

=== 和 !== 运算符。

使用 === 和 !== 运算符。 == 和 != 运算符会进行类型强制。在 特别是,不要使用 == 来比较 反对虚假值。

JSLint 非常严格,他们的 'webjslint.js' 甚至没有通过自己的验证。

【讨论】:

  • 很好的说明。这是真的,关于webjslint.js 没有验证——尽管我现在看到的大多数错误都与间距有关。显然,在使用 JSLint 审查 JavaScript 时,必须使用常识和合理的判断。
  • 使用always这个词会自动取消这句话的智慧。聪明的程序员不是教条主义的。他们在给定的情况下使用最好的。他们欢迎并接受任何内置于语言核心的工具,而不仅仅是用just never touch it 将其驳回。底线:我的代码更短(不仅仅是节省了一个 = 字符),因此我的网站加载速度更快,带宽成本更低,因此我的用户得到了更好的服务。
【解决方案6】:

如果您想测试虚假性。 JSLint 不允许

if (foo == null)

但确实允许

if (!foo)

【讨论】:

  • 使用 JSLint 推荐的 ===
  • @NarawGames 这个解决方案完全可以接受。
  • 这个答案不好。问题是这两个都意味着别的东西。 foo == null 检查 null 或 undefined。 !foo 检查 null、未定义、0 和空字符串。
  • @Markos 这个答案旨在成为让 JSLint 满意并保持代码逻辑完整的有用替代方案,而不是完全等价的。这就是为什么我在答案前加上“如果检查虚假”
【解决方案7】:

为了帮助解释这个问题并解释为什么 NetBeans (from) 7.3 开始显示此警告,这是从 NetBeans 错误跟踪器上的响应中摘录的,当时有人将此报告为错误:

在 JavaScript 中使用 === 而不是 == 是一种很好的做法。

== 和 != 运算符在比较之前进行强制类型转换。这很糟糕,因为 它导致 ' \t\r\n' == 0 为真。这可以掩盖类型错误。 JSLint 不能 可靠地确定 == 是否被正确使用,因此最好不要使用 == 和 != 并始终使用更可靠的 === 和 !== 运算符 而是。

Reference

【讨论】:

  • 我刚才也在使用 Netbeans 时发现了这个错误。奇怪的是,由于他们提供的奇怪的示例案例,他们会以警告严重性对待这个问题。
  • 我的意思是,这是真的,但是在很多用例中,人们知道两个比较的事物将属于同一类型,所以由于这个奇怪的案例,一个回车可能会与数字零进行比较,这就是 == 的所有用法都被认为是错误的原因。我发现虽然 === 更快,因为没有进行类型转换。我很惊讶我在 netbeans 之前没有发现这一点。
  • @oMiKeY 是的,我明白你的意思,他们本可以举出更现实的例子!
【解决方案8】:

嗯,它不会真的引起问题,它只是给你建议。要么接受,要么离开它。也就是说,我不确定它有多聪明。在某些情况下,它可能不会将其视为问题。

【讨论】:

  • 但是为什么要使用“预期”这个词呢?听起来你应该总是这样做。
  • 评估者正在寻找有效的响应,因为它正在尝试验证它。如果它没有得到有效的响应,那么它不是它所期望的。验证器首先假设一切正常,然后在遍历代码时指出错误。它不一定了解什么是无效响应,它只知道何时看到无效响应。它也可以反过来工作,根据什么是坏的规则故意搜索坏代码。白名单与黑名单。
  • 问题是“这真的有意义吗?”。鉴于这个问题,是的,确实如此。而且,那是五年前。耶稣。
猜你喜欢
  • 2016-08-21
  • 2011-06-08
  • 2015-07-14
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
相关资源
最近更新 更多