You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Object.assign({}, xyz)与Object.assign([], abc)是否存在差异?

关于Object.assign({}, xyz)和Object.assign([], abc)的差异详解

嘿,这个问题问得特别到位!我刚接手旧项目的时候也碰到过这种“前后不一致”的写法,当时差点以为是前任开发者写错了,直到仔细啃了Object.assign的文档才明白其中的门道。核心差异其实都源于目标参数的类型不同,咱们一步步拆解:

先搞懂Object.assign的本质

Object.assign(target, ...sources)的核心逻辑是:把所有源对象的可枚举属性依次复制到目标对象上,最后返回修改后的目标对象。所以目标对象的类型,直接决定了最终返回值的类型,以及属性复制的行为逻辑。


两种写法的具体差异

1. Object.assign({}, xyz):目标是空对象

  • 返回结果:永远是一个普通对象,哪怕xyz是数组或者类数组对象。
  • 复制逻辑:把xyz的所有可枚举属性(包括数组的索引、length属性,甚至自定义属性)都作为键值对复制到新对象里。
  • 示例:
    const arr = [1, 2, 3];
    arr.customProp = 'test'; // 给数组加个自定义属性
    
    const objCopy = Object.assign({}, arr);
    console.log(objCopy); // {0: 1, 1: 2, 2: 3, length: 3, customProp: 'test'}
    console.log(Array.isArray(objCopy)); // false
    
  • 适用场景:
    • 需要创建普通对象的浅拷贝,避免修改原对象;
    • 把数组/类数组对象转成键值对形式的普通对象;
    • 合并多个对象的属性到新对象中。

2. Object.assign([], abc):目标是空数组

  • 返回结果:永远是一个数组,哪怕abc是普通对象。
  • 复制逻辑:
    • 优先识别源对象中的数字类型索引(比如0、1),把对应值填充到数组的对应位置;
    • 源对象的非数字属性(比如自定义属性)会被作为数组对象的额外属性保留(因为数组本质也是对象);
    • 如果源对象有length属性,会同步修改数组的length(但如果数字索引不连续,length会取最大索引+1和源length的较大值)。
  • 示例:
    情况1:拷贝数组
    const arr = [1, 2, 3];
    const arrCopy = Object.assign([], arr);
    console.log(arrCopy); // [1, 2, 3]
    console.log(Array.isArray(arrCopy)); // true
    
    情况2:处理普通对象
    const obj = {name: 'Alice', age: 25};
    const arrFromObj = Object.assign([], obj);
    console.log(arrFromObj); // [] (没有数字索引,数组内容为空)
    console.log(arrFromObj.name); // 'Alice' (数组对象保留了这个属性)
    console.log(arrFromObj.length); // 0
    
    情况3:处理类数组对象
    const arrayLike = {0: 'a', 1: 'b', length: 2};
    const realArr = Object.assign([], arrayLike);
    console.log(realArr); // ['a', 'b']
    console.log(realArr.length); // 2
    
  • 适用场景:
    • 创建数组的浅拷贝;
    • 把类数组对象(比如arguments、DOM集合)转成真正的数组;
    • 合并多个数组的元素到新数组中(不过现在更常用[...arr1, ...arr2])。

关键注意点

两种写法都是浅拷贝!如果源对象里有嵌套的对象或数组,拷贝后的对象/数组里的嵌套值仍然是原对象的引用,修改它们会影响原对象。比如:

const obj = { nested: { key: 'value' } };
const copy = Object.assign({}, obj);
copy.nested.key = 'new value';
console.log(obj.nested.key); // 'new value' (原对象被修改了)

内容的提问来源于stack exchange,提问作者CodeMan03

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:45:55