奇怪的array.length替代语法

时间:2012-03-21 21:55:16

标签: javascript

这令我感到惊讶:

var parts = email.split('@');
if (parts < 2) {

参考:https://github.com/Kicksend/mailcheck/blob/master/src/jquery.mailcheck.js#L21-22

基本上,它看起来像:

var a = [null, null, null]
a < 2 // false

var b = [null]
b < 2 // true

所以它似乎有效,但我想知道为什么,它实际上会发生什么强制呢?因为这里的意图是保释,如果少于2个部分来自电子邮件字符串,我会期望它总是通过由于数组定义为真实 - 它应该创建一个至少有1个成员的数组,即使在一个空字符串

我总是喜欢使用array.length。以上安全吗?

5 个答案:

答案 0 :(得分:4)

这是一个字符串,然后是数字转换正在发生,因为与<运算符相比,数组不能直接。首先,它将进行字符串比较,但是使用数字,它将进行数字比较。

请注意:

  • [null, null, null] == ",,"
  • [null] == ""

  • +",,"NaN
  • +"" === 0

现在它有道理,因为0 < 2 === true但是NaN < 2 === false

因此,它确实不是一个有意义的表达。 [null, null] < 3false,因为"," < 3基本上正在NaN < 3

答案 1 :(得分:2)

使用<>运算符将数组与数字进行比较是不安全,可靠或正确的。你不应该这样做。

以下是从this O'Reilly book获取的转化规则:

  

这些比较运算符的操作数可以是任何类型。   但是,只能对数字和字符串进行比较   转换非数字或字符串的操作数。比较和   转换发生如下:

     

如果两个操作数都是数字,或两者都转换为数字,则它们是   比较数字。

     

如果两个操作数都是字符串或转换为字符串,则会对它们进行比较   作为字符串。

     

如果一个操作数是或转换为字符串而一个是或转换为a   number,运算符尝试将字符串转换为数字和   进行数值比较。如果字符串不代表a   number,它转换为NaN,比较为false。 (在   JavaScript 1.1,字符串到数字的转换会导致错误   而不是产生NaN。)

     

如果对象可以转换为数字或字符串,   JavaScript执行数字转换。这意味着,例如,   Date对象在数字上进行比较,对它有意义   比较两个日期,看一个是否早于另一个。

     

如果比较运算符的操作数不能同时存在   成功转换为数字或字符串,这些运算符   总是返回假。

     

如果任一操作数是或转换为NaN,则为比较运算符   总是产生错误。

在这种特殊情况下,由于没有数组转换为数字,最终会比较两个完全不可靠的字符串。

这是您应该只比较两个相同类型的项目的另一个原因。在这种特殊情况下,直接使用.length属性并使用:

也是更易读的代码
a.length > 2

答案 2 :(得分:2)

我觉得这不安全,因为:

[0, 0] > 1 // false

[0, 0] < Infinity // false

好的,它根本不是比较元素的数量。它比较了数组的字符串表示,因此NaN < Infinity给出了false。所以答案是否定的,它根本不是一个安全的选择,因为他们不会远程做同样的事情。它只对你有用,因为:

[null] < 2 -> null < 2 -> 0 < 2 -> true

[null, null, null] < 2 -> ',,' < 2 -> NaN < 2 -> false

答案 3 :(得分:1)

无法将数组转换为数字。这里发生的是数组被转换为字符串。

当数组转换为字符串时,内部JavaScript会array.join(',')

因此,['a','b']变为"a,b"

[null]""[null,null]","。这是因为null被转换为空字符串。

因此,[null,null] < 2"," < 2,这是假的。

要获得数组的长度,请使用.length

答案 4 :(得分:1)

哦,它的安全,它只是没有比较你认为它的比较。

表达式parts < 2正在将数组与数字进行比较。要完成此比较,JavaScript必须将这两个值转换为通用类型,并且唯一可用的是字符串。数组对象的toString()方法连接数组元素的每个字符串值w /逗号,字符串值null为空字符串。因此,您的测试表达式正在执行",," < "2""" < "2",我确信这不是预期的。

只要你不在数组上使用delete(使用slice代替),使用长度应该是完全安全的。