【问题标题】:Testing for an empty array in JavaScript Performance在 JavaScript 性能中测试空数组
【发布时间】:2013-07-07 03:30:38
【问题描述】:

http://jsperf.com/testing-for-empty-array

我想知道在 JavaScript 中测试空数组的最佳方法是什么,并发现了一些奇怪的结果。据我所知,你永远不应该使用:

if (arr == true)
  // do stuff

我认为与以下内容相同的解释:

if (arr)
  // do stuff

使用arr == true 速度明显变慢有什么原因吗?

【问题讨论】:

  • 不是 arr.length !== 0 更快吗?
  • arr == true 不是总是假的吗?是否为空?
  • 但它不应该在if (arr) 案例中进行相同的测试吗?
  • @RyanAllred - 数组的第一个元素可以是值undefined。 JavaScript 不必遍历数组来确定其长度。请注意,如果arr 是一个数组,则if(arr) 将始终为true,无论是否为空。您需要测试arr.length(也可能使用Array.isArray(arr))来测试arr 是否为空数组。
  • @RyanAllred 不要依赖这样的基准。 jsperf 确保浏览器不在这里使用他们的优化编译器,如果你需要性能,你将在你的应用程序中使用优化编译器。那么在数组中存储不同的东西时性能结果可能会有所不同(比如小可以优化的整数),或者数组是否为空。最好的方法是只使用 !a.length 或 a.lent`,然后如果您分析并发现您需要优化该位,如果它对您的应用程序有显着改进,您可以用其他东西替换它。

标签: javascript arrays performance


【解决方案1】:

测试数组是否为空的唯一好方法是使用arr.length

让我们看看不同的情况。

  1. if(arr === true) 将始终为 false,因为数组不是布尔值。

    if(arr !== false && arr !== true) 将出于同样的原因返回 true!

  2. if(arr) 将返回 true 或 false,这取决于是否设置了数组。如果是var arr = [],会返回true,但它是一个空数组。

    其实即使var不是数组,也会返回true。

  3. if(arr[0]) 将在索引为 0 的单元格中有值时返回 true。即使在那里,也不意味着它是空的,因为您可以设置像 var arr=[]; arr[1] = 'value'arr[0] 这样的单元格将返回 false因为它没有设置,但是数组的长度为2(一个单元格)。

最后,查看数组是否为空的最佳方法是:if(arr && arr.length)

如果您知道您已经创建了数组,则不需要检查arr 是否存在,否则,它将防止任何错误。然后,您检查数组的长度,如果您没有像这样更改值:arr.length = 1000,它会告诉您数组是否为空。

【讨论】:

  • 其实console.log([1] == true)会打印true。请记住,在 JavaScript 中,== 会进行自动类型转换。
  • 在#3中,如果你设置arr[0],则长度为2。只是说。
  • spec 在这方面非常清楚。 [1] == true => [1] == 1 => '1' == 1 => 1 == 1 => true
  • 正在进行一系列复杂的类型转换。首先,true 被转换为一个数字(即1)。然后,数组被转换为原始字符串,即字符串'1'(数组中的值的逗号分隔列表)。然后字符串也被转换为数字。如果数字匹配,则认为这两个值相等。 (注意左边可能是NaN。)
  • ^ 是的,这比我的评论解释得更好。 =]
【解决方案2】:

它必须首先将数组转换为空字符串,然后从那里转换为布尔值以与true 进行比较,因为您不能直接将数组与布尔值进行比较。铸造很昂贵。

【讨论】:

  • 为什么要这么做?
  • 为什么它必须做什么?比较?演员?
  • @chris - 相等比较的规则,包括需要什么类型转换,在EcmaScipt specification 的第 11.9.3 节中有详细说明。
  • 为什么要转换成字符串?一个对象总是真实的,不是吗?
  • 这是#11.9.3 的直接链接。 @chris 步骤 8-9 在算法的第二遍(第一个将布尔值转换为数字)上的对象上调用 ToPrimitive。数组的ToPrimitive 是由, 连接的元素的字符串表示形式。
猜你喜欢
  • 2012-12-26
  • 2011-11-23
  • 2017-07-27
  • 1970-01-01
  • 2014-09-24
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2012-10-15
相关资源
最近更新 更多