前端开发中的常用工具函数(八)

二十、Object.assign() 方法:

1. 基本语法

Object.assign 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

javascript 复制代码
Object.assign(target, ...sources)
  • target(目标对象):必需。接收属性的对象。
  • sources(源对象):可选。一个或多个源对象,它们的属性将被复制到目标对象。

核心规则:

  1. 如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。
  2. 后面的源对象的属性将类似地覆盖前面的源对象的属性。

2. 基础示例

(1) 基本合并

javascript 复制代码
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

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

console.log(target);        // 输出: { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target); // 输出: true (返回的是同一个对象引用)

(2) 合并多个对象

javascript 复制代码
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };

const merged = Object.assign({}, obj1, obj2, obj3);
console.log(merged); // 输出: { a: 1, b: 2, c: 3 }

小技巧 :如果不希望修改原对象,通常将 target 设为一个空对象 {}

示例:

3. 企业开发中的实际应用场景

场景一:组件默认配置与用户自定义配置合并

这是 Object.assign 最经典的用法。开发通用组件(如弹窗、表格)时,通常有一份默认配置,用户传入的配置需要覆盖默认值。

javascript 复制代码
// 默认配置
const defaultOptions = {
    width: 100,
    height: 50,
    color: 'blue',
    draggable: false
};

// 用户传入的自定义配置
const userOptions = {
    width: 200,
    color: 'red'
};

// 合并策略:创建一个新对象,先放入默认值,再覆盖用户值
const finalOptions = Object.assign({}, defaultOptions, userOptions);

console.log(finalOptions);
// 输出: { width: 200, height: 50, color: 'red', draggable: false }

场景二:Redux/State 状态更新(不可变数据)

在 Redux 或 React 的 Class 组件时代,我们不能直接修改 state,而是需要返回一个新的对象。Object.assign 是实现浅拷贝更新的标准写法。

javascript 复制代码
const initialState = {
    loading: false,
    data: [],
    error: null
};

// 模拟 Reducer 中的状态更新
function reducer(state = initialState, action) {
    switch (action.type) {
        case 'FETCH_START':
            // 返回一个新对象,保持原 state 不变
            return Object.assign({}, state, {
                loading: true
            });
        case 'FETCH_SUCCESS':
            return Object.assign({}, state, {
                loading: false,
                data: action.payload
            });
        default:
            return state;
    }
}

场景三:为对象动态添加属性与方法

虽然可以直接 obj.key = value,但在批量添加或需要保持代码整洁时,Object.assign 很有用。

javascript 复制代码
class User {
    constructor(name) {
        this.name = name;
    }
}

// 动态混入功能(类似于 Mixin 模式)
const features = {
    sayHello() {
        console.log(`Hello, I'm ${this.name}`);
    },
    walk() {
        console.log(`${this.name} is walking`);
    }
};

const user = new User('Jack');
Object.assign(user, features);

user.sayHello(); // 输出: Hello, I'm Jack

4. 注意事项

(1) 浅拷贝------ 最大的坑

这是新手最容易犯的错误。Object.assign 只能拷贝第一层属性。如果源对象的属性值是一个对象(引用类型),拷贝的是该对象的引用。

javascript 复制代码
const source = {
    a: 1,
    b: { 
        c: 2 
    }
};

const target = Object.assign({}, source);

// 修改 target 中嵌套对象的值
target.b.c = 100;

// 悲剧发生了:源对象也被修改了!
console.log(source.b.c); // 输出: 100

避坑指南 :对于深层对象结构,推荐使用 JSON.parse(JSON.stringify(obj)) 进行深拷贝(注意函数和 undefined 会丢失),或使用 Lodash 的 _.cloneDeep

(2) 同名属性的完全覆盖

不仅是值会被覆盖,属性描述符也会被覆盖。

javascript 复制代码
const source = Object.defineProperty({}, 'name', {
    value: 'Source',
    writable: false // 不可写
});

const target = { name: 'Target' };

Object.assign(target, source);

// assign 只拷贝值,不拷贝属性描述符
// target.name 变成了 'Source',但 writable 特性并未复制过来,而是恢复默认
console.log(target.name); // 'Source'

(3) 数组的处理

如果参数是数组,Object.assign 会把数组视为对象处理,键名是索引。

javascript 复制代码
const arr1 = [1, 2, 3];
const arr2 = [4, 5];
const result = Object.assign(arr1, arr2);

console.log(result); // 输出: [4, 5, 3] (不是合并数组,而是属性覆盖)
// 解释: arr2 的 '0':4 覆盖了 arr1 的 '0':1, '1':5 覆盖了 '2':2,'3'未受影响

避坑指南 :合并数组请使用 [...arr1, ...arr2]arr1.concat(arr2)

相关推荐
江畔柳前堤4 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
Wang's Blog5 小时前
Go-Zero 项目开发47:自研微服务框架的必要性与核心结构设计
开发语言·微服务·golang
白鸽(二般)5 小时前
MinIO Java Client API
java·开发语言
hPw0eKIqD5 小时前
C++ 模板参数推导问题小记(非推导上下文)
开发语言·c++
90后的晨仔6 小时前
从 H5 到 uni-app:一篇写给前端小白的"翻译指南"
前端·vue.js·前端框架
临床数据科学和人工智能兴趣组6 小时前
要使用 R Markdown,首先需要安装 R 和 RStudio,接着安装 rmarkdown 包
开发语言·数据挖掘·数据分析·r语言·r语言-4.2.1
Nebula嵌入式6 小时前
【C语言】09-深入解析main函数
linux·c语言·开发语言·嵌入式
陈随易6 小时前
moon,apt和yum之外linux系统命令安装新选择
前端·后端·程序员
IT小盘7 小时前
13-企业Prompt模板-角色任务约束与输出格式
java·前端·prompt
徐小夕7 小时前
开源!我用SQLite + DuckDB打造了一款可视化AI问数平台
前端·算法·github