Object.assign 过时了?现代对象合并的正确做法与最佳实践

AI 概述
最开始的时候Object.assign 的两大“原罪”1. 可变性:意外的副作用2. 浅拷贝:深层对象的陷阱解决方案:展开语法 前端开发过程中经常会用到Object.assign() ,它也不负众望,一直是我们的得力助手,但随着 JavaScript 语言的飞速发展,Object.assign()使用问题也愈发明显。 最开始的时候 在 ES6 推出之...
目录
文章目录隐藏
  1. 最开始的时候
  2. Object.assign 的两大“原罪”
  3. 解决方案:展开语法

前端开发过程中经常会用到Object.assign() ,它也不负众望,一直是我们的得力助手,但随着 JavaScript 语言的飞速发展,Object.assign()使用问题也愈发明显。

最开始的时候

在 ES6 推出之前,合并对象通常需要手动遍历属性或借助 jQuery.extend 等库函数,Object.assign() 的出现无疑是一个巨大的进步,其基本用法如下:

const target = { a: 1, b: 1 };
const source = { b: 2, c: 2 };

const result = Object.assign(target, source);

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

它将所有可枚举的自有属性从一个或多个源对象复制到目标对象,并返回目标对象。看起来不错,对吗?但魔鬼藏在细节中。

Object.assign 的两大“原罪”

Object.assign 的问题不在于它不能用,而在于它很容易被误用,从而导致难以追踪的 bug。

1. 可变性:意外的副作用

Object.assign 会修改它的第一个参数(即目标对象)。

在上面的例子中,target 对象被直接修改了,这在推崇不可变性的现代前端框架(如 React、Vue)中是一个巨大的隐患。

为了避免修改原始对象,我们通常会这样做:

const obj1 = { a: 1 };
const obj2 = { b: 2 };
//使用一个空对象作为 target,避免修改原始对象
const newObj = 0bject.assign({}, obj1, obj2); // { fa:1,b:2 }
console.log(obj1);// { a: 1 }(未被修改)

这种写法虽然解决了问题,但显得有些冗长和笨拙。

2. 浅拷贝:深层对象的陷阱

这是 Object.assign 最致命的缺陷,它执行的是浅拷贝,而不是深拷贝,这意味着如果对象的属性值是另一个对象,它只会复制那个对象的引用,而不是对象本身。

让我们看一个例子:

const user = { details: { age: 30 } };
const updatedInfo = { details: { city: 'London' } };
const updatedUser = Object.assign({}, user, updatedInfo);
// 问题来了
updatedUser.details.age = 31;
// 原始对象的嵌套属性也被修改了!
console.log(user.details.age); // 31  <-- 这是一个巨大的副作用!

解决方案:展开语法

对象的展开语法,几乎在所有方面都优于 Object.assign,目前已成为社区合并对象的首选。

它天生就是为了创建新对象而生,完美契合不可变性的理念。

const obj1 = { a:1 };
const obj2 = { b:2 };

const newObj = { ...objl, ...obj2 };// { a:1,b:2 }
console.log(obj1); // {a:1}(未被修改)

代码不仅更简洁、更具可读性,而且从根本上避免了修改原始对象的风险。

让我们用展开语法重写刚才那个嵌套对象的例子:

const updatedUser = {
  ...user,
  details: {
    ...user.details, // 关键在这里!需要手动展开嵌套对象
    ...updatedDetails
  }
};

updatedUser.details.age = 31;
console.log(user.details.age); // 30 (安全了!)

通过手动展开嵌套的 details 对象,避免了引用问题,虽然比 Object.assign 多了一步,但它让数据流向变得清晰可见。

如果不想手动展开嵌套,使用 structuredClone 深拷贝即可:{ …structuredClone(user), updatedInfo};

以上关于Object.assign 过时了?现代对象合并的正确做法与最佳实践的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Object.assign 过时了?现代对象合并的正确做法与最佳实践

发表回复