TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码

JavaScript的Object.assign方法详解:深拷贝还是浅拷贝?

2025-07-18
/
0 评论
/
3 阅读
/
正在检测是否收录...
07/18


一、什么是Object.assign?

Object.assign()是ES6引入的一个对象操作方法,用于将一个或多个源对象(source)的可枚举属性复制到目标对象(target)。其基本语法为:

javascript Object.assign(target, ...sources)

当我们需要合并多个对象时,这个方法显得尤为实用。比如在React/Vue的状态管理、配置对象合并等场景中经常能看到它的身影。

二、核心特性与使用示例

1. 基础用法

javascript
const target = { a: 1 };
const source = { b: 2 };
const result = Object.assign(target, source);

console.log(result); // { a: 1, b: 2 }
console.log(target === result); // true

注意点:
- 方法会修改第一个参数(目标对象)
- 返回值为修改后的目标对象
- 同名属性会被后续源对象覆盖

2. 多对象合并

javascript
const user = { name: 'Alex' };
const job = { position: 'FE Developer' };
const company = { name: 'TechCorp' };

const employee = Object.assign({}, user, job, company);
// { name: 'TechCorp', position: 'FE Developer' }

3. 只复制可枚举属性

javascript
const obj = Object.create({ inheritProp: '不可枚举' }, {
enumerableProp: {
value: '可枚举',
enumerable: true
}
});

console.log(Object.assign({}, obj));
// { enumerableProp: '可枚举' }

三、关键问题深度解析

1. 浅拷贝的本质

Object.assign执行的是浅拷贝(shallow copy),当属性值为引用类型时,复制的是引用地址:

javascript
const obj1 = { nested: { value: 1 } };
const obj2 = Object.assign({}, obj1);

obj2.nested.value = 2;
console.log(obj1.nested.value); // 2 (原始对象也被修改)

2. 与扩展运算符的对比

javascript
// 等效写法
const cloneA = Object.assign({}, obj);
const cloneB = { ...obj };

// 细微差别:
// - Object.assign会触发setter,而扩展运算符不会
// - 扩展运算符在TypeScript中有更好的类型推断

3. 特殊值处理规则

| 输入类型 | 处理方式 |
|----------------|-------------------------|
| undefined/null | 被忽略 |
| 原始值 | 转为包装对象后复制属性 |
| Symbol属性 | 可以被正常复制 |

javascript Object.assign({}, undefined); // 不报错,返回{} Object.assign({}, 123); // {} Object.assign({}, 'abc'); // {0:'a', 1:'b', 2:'c'}

四、实战应用场景

1. 默认参数覆盖

javascript function init(config) { const defaults = { duration: 300, easing: 'linear' }; return Object.assign({}, defaults, config); }

2. 不可变数据模式

javascript // Redux reducer中的状态更新 function reducer(state, action) { return Object.assign({}, state, { loading: false, data: action.payload }); }

3. 原型链属性复制

javascript function cloneProto(instance) { return Object.assign( Object.create(Object.getPrototypeOf(instance)), instance ); }

五、局限性及替代方案

虽然Object.assign很方便,但在以下场景需要注意:

  1. 深嵌套对象:需要配合递归或使用库如lodash.cloneDeep
  2. 非可枚举属性:需要使用Object.getOwnPropertyDescriptors
  3. 性能敏感场景:大数据量时考虑专有方案

javascript
// 深拷贝替代方案
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}

// 现代浏览器支持的新API
const deepClone = structuredClone(obj);

六、最佳实践建议

  1. 总是以空对象作为第一个参数来避免副作用javascript
    // 不推荐
    Object.assign(existingObj, newProps);

    // 推荐
    const newObj = Object.assign({}, existingObj, newProps);

  2. 对TypeScript项目,考虑使用类型安全的变体:
    typescript function safeAssign<T extends object>(target: T, ...sources: Partial<T>[]): T { return Object.assign(target, ...sources); }

  3. 在需要保留原型链时,组合使用Object.create:
    javascript function clone(obj) { return Object.assign( Object.create(Object.getPrototypeOf(obj)), obj ); }

浅拷贝ES6特性Object.assignJavaScript对象合并对象属性复制
朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/33085/(转载时请注明本文出处及文章链接)

评论 (0)