javascript - 我能确定 array.slice() 总是和 array.slice(0) 一样工作吗?

标签 javascript

我一直使用不带参数的 .slice() 方法来制作 JavaScript Array 的副本。这在我尝试过的每个浏览器和 JavaScript 环境中都运行良好:它被视为与 .slice(0) 相同。

这只是风格问题,但对我来说,完全省略 start 参数可以更清楚地表明我们不是在获取数组的任何特殊子切片,而是想要整个数组的副本

然而,MDNMSDN假设 array.slice() 的第一个参数是必需的。只有第二个参数是可选的。其他在线资源,例如 TutorialsPointW3Schools说同样的话。 (不,我不推荐 W3Schools!只是指出他们在这个问题上同意 MDN 和 MSDN。)

我只是运气好吗?是否存在 array.slice() 不起作用的浏览器或其他 JavaScript 环境?

最佳答案

所有这些在线引用都是错误的。

至少如果我们谈论的是符合标准的浏览器和运行时。

ECMA-262 standard要求任何符合要求的实现将 array.slice()array.slice(0) 相同。

我们是这样知道的。

首先我们看Section 15.4.4.10 , "Array.prototype.slice (start, end)":

The slice method takes two arguments, start and end, and returns an array containing the elements of the array from element start up to, but not including, element end (or through the end of the array if end is undefined)…

这是什么?甚至没有提到 end 是可选的。 开始结束都需要吗?

是的,他们是。但我们需要看看其他地方才能理解这意味着什么。

Section 15 , "Standard Built-in ECMAScript Objects"说(在第四段):

Unless otherwise specified in the description of a particular function, if a function or constructor described in this clause is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the undefined value.

这与其他方法的指定方式一致。例如,我们知道 array.sort() 的比较函数参数是可选的,但是 Section 15.4.4.11 “Array.prototype.sort (comparefn)”没有说明 comparefn 参数是可选的。它只是描述当 comparefn 是否为 undefined 时要做什么。

所以现在我们知道 array.slice() 被解释为 array.slice(undefined,undefined)。然后,继续 Section 15.4.4.10 ,我们找到相关步骤:

5 . Let relativeStart be ToInteger(start).

ToIntegerSection 9.4 中描述,其中前两个步骤是相关的:

1 . Let number be the result of calling ToNumber on the input argument.
2 . If number is NaN, return +0.

ToNumberSection 9.3 中找到,其中表中的第一个条目表示当其参数​​类型为未定义时,结果为 NaN

因此,array.slice() 缺少的第一个参数被视为 undefined 并且该值被传递给 ToNumber,后者返回 NaN。这会导致 ToInteger 返回 0(或他们在这里所说的 +0),这就是 array.slice() 使用的值。

因此,array.slice()array.slice(0) 相同。如果一个实现不那样对待它,它就不符合 ECMA-262 标准。

当然,那是标准,然后才是现实世界。

如果我们对 .slice()第二个参数进行同样的分析,我们会得出结论,所有这些都应该工作相同(在其他类似的变体):

array.slice()
array.slice( 0 )
array.slice( undefined )
array.slice( 0, undefined )
array.slice( undefined, undefined )

但是,正如@Pumbaa80 在评论中指出的那样,最后两个版本在 IE8(也不在 IE7)中不起作用!

但至少我担心的简单 array.slice() 案例在这些旧浏览器中确实有效,并且应该继续在遵循标准的任何浏览器或运行时中工作。

关于javascript - 我能确定 array.slice() 总是和 array.slice(0) 一样工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18180844/

相关文章:

php - Javascript 将 PHP Json 转换为 javascript 数组

javascript - 如何在 react 中使用gapi

javascript - 如何通过不显眼的验证更改 View 模型中 StringLength 属性的默认 ErrorMessage

javascript - 如何将数组转换为对象

javascript - 如何在没有实际页面刷新的情况下更新页面 html 和 url

javascript - HTML5 视频持续时间无限而 readyState = 4

javascript - 具有外部 block 变量的事件

每次有人访问我的应用程序选项卡时,JavaScript 都会刷新页面

visual studio 2013/resharper 中的 javascript/node.js intellisense 有问题

javascript - 如何在 JavaScript 中自动完成 API 调用的 JSON 响应?