【问题标题】:What should be the value of [1,2,3].slice(1,undefined)?[1,2,3].slice(1,undefined) 的值应该是多少?
【发布时间】:2011-08-06 17:04:29
【问题描述】:

我发现在处理上有所不同

[1,2,3].slice(1, undefined)

在 chrome(返回 [2,3])和 firefox(返回 [])之间。

当然,两者都同意将 [2, 3] 作为值

[1,2,3].slice(1)

他们也都同意[] 的值

[1,2,3].slice(1, null)

这两个哪个是正确的?还是标准中没有明确规定?

【问题讨论】:

  • 什么版本的火狐?使用undefined 时,我在 FF5 中没有得到该结果。 null 的结果是预期的,因为它将转换为 0
  • 你不打算分享你用的是什么版本的FF吗?想知道这个问题在 FF4 中是否仍然存在。
  • @Patrick:问题出现在 ubuntu 10.10 上的 firefox 3.6.18 中。

标签: javascript firefox google-chrome


【解决方案1】:

The specification says:

7。如果endundefined,让relativeEndlen;否则让 relativeEnd 为 ToInteger(end)。

您使用的是哪个 Firefox 版本? Firefox 5 正确地给了我[2, 3]更新: Firefox 3.6 确实返回了一个空数组。

我不知道这里出了什么问题,因为如果你在没有第二个参数的情况下调用slice()end 也将是undefined

更新:

玩了一会儿,如果传递给.slice() 的第二个参数是NaN,似乎返回了一个空数组。示例(+undefined 返回 NaN):

> [1,2,3].slice(1, +undefined)
> []

这在 Firefox 和 Chrome 中是一样的。

不幸的是,这也不符合规范,因为ToInteger(NaN) [spec] 应该返回0,所以数组实际上应该被切片到末尾。

我并没有声称这是它在某些 Firefox 版本中无法正常工作的原因,我不知道具体实现。

轻微迷失方向的事件......没关系。

【讨论】:

  • 他们可能在检查有多少个参数而不是检查undefined,这就是为什么如果你在没有第二个参数的情况下调用它会起作用。
  • @Matthew:可能,但这不是唯一的原因。他们似乎也没有使用ToIngeger,因为ToInteger(undefined) 应该给0(没关系)。也许他们使用了ToNumber(),通过undefined,得到NaN。这确实返回了一个空数组。
  • “很遗憾,这也不符合规范,因为 ToInteger(NaN) [spec] 应该返回 0,因此实际上应该将数组切片到末尾。” i> 我认为您混淆了第一个和第二个参数。以0 作为第一个参数(没有第二个参数),它被切到最后。使用0 作为第二个参数,您已经有效地将0 确定为添加到返回的新数组时发生的迭代次数,因此,正确返回了一个空数组。
  • @Felix:当然,除了 ECMAScript 规则的细节以及各种浏览器无法正确实现它们之外,还有更重要的事情需要思考。 ;o)
【解决方案2】:

我不确定这是否在标准中定义,但我可以告诉你这是一个棘手的调用。 就像 Felix 说的,这不是标准行为,但我能想到为什么会这样。

您可能知道undefined 是设置为调用函数时未提供的参数的值。然而,在您的示例中,您实际上传递的是未定义的,因此传递的参数实际上是两个并且反映在 arguments.length 中。

所以从你所说的情况很容易想象,在 Chrome 中,第二个参数正在使用 typeof param2 == "undefined" 进行检查,而在 Firefox 中,他们使用 arguments.length > 1。因此,并不是(完全)Firefox 搞错了,就像 Felix 建议的那样,他们只是假设 undefined 实际上永远不会直接作为第二个参数传入。

像这样使用undefined,你可能会遇到几个这样的情况,我建议你不要使用它!

【讨论】:

  • 可靠代码的好建议 - 但行为绝对是标准化的。
  • +1 关于如何处理参数的好猜测。我不知道实现,但他可能是一种解释(尽管这些方法是用本机代码实现的,而不是 JavaScript)。
  • 是的,确实我已经修复了我的代码,以避免调用切片未定义作为第二个参数(它是生成的 javascript)。无论如何,很高兴看到该标准涵盖了这种情况,并且版本 5 中的 firefox 调整了它的行为。
  • “所以它(完全)不是 Firefox 弄错了……” 我会说完全是 FF 弄错了.所需的步骤非常具体。 +1 虽然他们似乎很可能试图走捷径,并最终在undefined 上进行 toInteger 转换,从而导致0
  • @patrickdw:实际上转换为0 会很好,因为算法的下一步是:let final be min(relativeEnd, len)。 所以如果这将导致0,将采用数组的实际长度(当您传递null 时会发生这种情况)。也许他们正在做一些转换,结果是NaN,这会在每个浏览器中给出一个空数组。试试[1,2,3].slice(1, +undefined)
【解决方案3】:

帖子中测试的 Firefox 的版本在这里是错误的。 但是,Firefox 5 可以按照规范运行[1,2,3].slice(1, undefined) 的计算结果为 [2,3]

来自ECMAScript ed5 standard

slice 方法接受两个参数 start 和 end,并返回将此对象转换为 String 的结果的子字符串,从字符位置 start 开始,运行到但不包括字符位置 end (或如果 end 未定义,则通过字符串的末尾)...

编码愉快。

【讨论】:

    猜你喜欢
    • 2018-02-07
    • 2021-04-01
    • 2020-12-13
    • 1970-01-01
    • 2011-02-10
    • 2023-03-21
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多