Array.prototype.slice.call(arguments)是ES5遗留写法,现应优先用剩余参数...args替代,因其语义清晰、性能优且为真数组;其他场景可选Array.from或扩展运算符。

Array.prototype.slice.call(arguments) 是 ES5 时代处理函数参数的惯用写法,现在早已不是首选。识别它是否“老旧”,关键看三点:是否在传统函数里手动转换 arguments、是否用 .call() 借方法、是否没用到任何 ES6+ 语法特性。一旦看到这行代码,基本可以判定是遗留代码,该升级了。
一眼识别老旧写法的特征
这类写法通常出现在以下场景中:
- 函数体开头就有一行
const args = Array.prototype.slice.call(arguments)或[].slice.call(arguments) - 函数是
function声明式(非箭头函数),且内部还用了arguments - 没有使用
...、Array.from、for...of等现代语法 - 项目已支持 ES2015+,但代码里仍保留这种兼容 IE8 的写法
最直接的现代替代:剩余参数(...args)
这是语义最清晰、性能最好、也最推荐的替换方式。它天然就是真数组,无需转换。
- 把
function sum() { const args = Array.prototype.slice.call(arguments); ... } - 改成
function sum(...args) { /* args 直接可用 */ } - 箭头函数也完全支持:
const sum = (...args) => args.reduce((a, b) => a + b, 0);
其他合理替代方案(按优先级)
当无法直接改参数签名时(比如要封装已有函数、或处理非 arguments 的类数组),可选:
-
Array.from(arrayLike):安全、语义明确,能处理
length: undefined等边界情况,且支持 NodeList、HTMLCollection、甚至 Map/Set 的键值对 -
[...arrayLike]:简洁,但要求对象有
Symbol.iterator;注意旧版 DOM 中部分 HTMLCollection 不可迭代,可能报错 -
扩展运算符 + 数组字面量组合:如
[...document.querySelectorAll('div')],比Array.from()更轻量,日常 DOM 操作中足够用
为什么不该再用 slice.call?
它不是错,而是过时的权衡:
- 只适用于“有 length + 数字索引”的类数组,不支持真正的可迭代对象(如 Set)
- 遇到
arguments.length === NaN会静默返回空数组,行为难预测 - 在箭头函数里直接失效(
arguments不存在) - 现代引擎对
...和Array.from都做了深度优化,性能差距已可忽略










