javascript中浅拷贝arguments的最简方法是array.from()或扩展运算符[...arguments],二者均生成新真数组,保持原引用/原始值,且安全可靠;其他方法如slice.call或json序列化均存在兼容性或语义缺陷。

JavaScript 中 arguments 是一个伪数组(类数组对象),它没有数组的内置方法(如 slice、map),但有 length 和按数字索引访问的属性。浅拷贝 arguments 的目标是创建一个**新的真数组**,其中每个元素是原 arguments 中对应位置的**引用值(对对象/函数)或原始值(对字符串、数字等)**。
用 Array.from() 最简洁可靠
Array.from() 专为类数组对象设计,能安全读取 arguments.length 并逐项拷贝,返回新数组:
- 支持所有环境(ES6+)
- 自动处理
length边界,不会多拷或少拷 - 对嵌套对象只做浅层复制(符合浅拷贝定义)
function fn() {
const args = Array.from(arguments); // ✅ 浅拷贝
args.push('new'); // 不影响原 arguments
return args;
}
用扩展运算符 [...arguments](推荐现代写法)
在支持 ES2015+ 的环境中,扩展运算符语法更直观,语义清晰:
- 本质也是调用
arguments的可迭代协议(Symbol.iterator),但arguments在现代引擎中已默认实现该协议 - 注意:IE 完全不支持,Node.js 早期版本(
function fn() {
const args = [...arguments]; // ✅ 简洁、易读
return args;
}
用 Array.prototype.slice.call()(兼容老环境)
这是 ES5 时代的经典方案,利用数组方法借用到类数组上:
- 依赖
slice的“类数组调用”能力,传入arguments作为this - 兼容性极好(IE6+ 都支持)
- 注意:不能直接写
arguments.slice(),因为arguments没有slice方法
function fn() {
const args = Array.prototype.slice.call(arguments); // ✅ 兼容性强
return args;
}
避免直接赋值或错误用法
以下方式**不是浅拷贝**,或根本不可行:
-
const args = arguments;→ 只是引用赋值,修改args会影响arguments内部(虽然arguments本身不可重新赋值,但某些操作如args[0] = ...在非严格模式下会同步影响实参) -
Array.prototype.map.call(arguments, x => x)→ 虽然可行,但比slice或Array.from多余,且无必要遍历加工 -
JSON.parse(JSON.stringify(arguments))→ 不是浅拷贝,且会丢失函数、undefined、Symbol、Date 等类型,完全不可用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











