千家信息网

javascript的Object.assign()怎么用

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇"javascript的Object.assign()怎么用"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获
千家信息网最后更新 2026年11月02日javascript的Object.assign()怎么用

这篇"javascript的Object.assign()怎么用"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"javascript的Object.assign()怎么用"文章吧。

如下:

const defaultOpt = {    key1: xxx,    key2: {        dd: ee    },    .....};// deepCopy为某个实现深拷贝的方法const opt1 = deepCopy(defaultOpt);opt1.....const opt2 = deepCopy(defaultOpt);opt2.....

深拷贝和浅拷贝

这里也涉及到一个深拷贝和浅拷贝的概念。javascript中存储对象都是存地址的,所以浅拷贝是都指向同一块内存区块,而深拷贝则是另外开辟了一块区域。

下面实例也可以看出这一点:

// 浅拷贝const a = {t: 1, p: 'gg'};const b = a;b.t = 3;console.log(a); // {t: 3, p: 'gg'}console.log(b); // {t: 3, p: 'gg'}//深拷贝const c = {t: 1, p: 'gg'};const d = deepCopy(c);d.t = 3;console.log(c); // {t: 1, p: 'gg'}console.log(d); // {t: 3, p: 'gg'}

可以明显看出,浅拷贝在改变其中一个值时,会导致其他也一起改变,而深拷贝不会。

Object.assign()

我需要的是深拷贝的方法,然后发现原来es6 中有Object.assign() 这个方法,感觉可以拿来用了。

贴一下两个官方例子:

// Cloning an objectvar obj = { a: 1 };var copy = Object.assign({}, obj);console.log(copy); // { a: 1 }
// Merging objectsvar o1 = { a: 1 };var o2 = { b: 2 };var o3 = { c: 3 };var obj = Object.assign(o1, o2, o3);console.log(obj); // { a: 1, b: 2, c: 3 }console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.

是不是很完美,又可以clone又可以merge。在我这种情况下,我觉得我的代码量又可以减少了,比如:

const defaultOpt = {    title: 'hello',     name: 'oo',     type: 'line'};// 原来可能需要这样const opt1 = deepCopy(a);opt1.title = 'opt1';opt1.type = 'bar';opt1.extra = 'extra'; // 额外增加配置// 现在只要这样const opt2 = Object.assign({}, a, {    title: 'opt2',     type: 'bar',     extra: 'extra'});

不过,很快,问题出现了,那就是

merge和我想象的不一样

且看例子:

const defaultOpt = {    title: {        text: 'hello world',        subtext: 'It\'s my world.'    }};const opt = Object.assign({}, defaultOpt, {    title: {        subtext: 'Yes, your world.'    }});console.log(opt);// 预期结果{    title: {        text: 'hello world',        subtext: 'Yes, your world.'    }}// 实际结果{    title: {        subtext: 'Yes, your world.'    }}

原本想的是它只会覆盖subtext ,然而其实它直接覆盖了整个title ,这个让我比较郁闷,相当于它只merge根属性,下面的就不做处理了。

代码只能重构成相对麻烦一点的:

const defaultOpt = {    title: {        text: 'hello world',        subtext: 'It\'s my world.'    }};const opt = Object.assign({}, defaultOpt);opt.title.subtext = 'Yes, your world.';console.log(opt);// 结果正常{    title: {        text: 'hello world',        subtext: 'Yes, your world.'    }}

这样用虽然麻烦一点,但是也还好,可以用了。不过。。。很快,又出现问题了,如下:

const defaultOpt = {    title: {        text: 'hello world',        subtext: 'It\'s my world.'    } };const opt1 = Object.assign({}, defaultOpt);const opt2 = Object.assign({}, defaultOpt);opt2.title.subtext = 'Yes, your world.';console.log('opt1:');console.log(opt1);console.log('opt2:');console.log(opt2);// 结果opt1:{    title: {        text: 'hello world',        subtext: 'Yes, your world.'    }}opt2:{    title: {        text: 'hello world',        subtext: 'Yes, your world.'    }}

上面结果发现两个配置变得一模一样,而其实我们并没有去更改opt1 的subtext ,只是改了opt2 的。

这说明一点:在title 这一层只是简单的浅拷贝 ,而没有继续深入的深拷贝。

这里不经让我怀疑这个接口到底是怎么实现的,它到底是不是和我所想的一样。

翻了一下官方文档,发现它写得一个Polyfill ,代码我加了点注释如下:

if (!Object.assign) {    // 定义assign方法  Object.defineProperty(Object, 'assign', {    enumerable: false,    configurable: true,    writable: true,    value: function(target) { // assign方法的第一个参数      'use strict';      // 第一个参数为空,则抛错      if (target === undefined || target === null) {        throw new TypeError('Cannot convert first argument to object');      }      var to = Object(target);      // 遍历剩余所有参数      for (var i = 1; i < arguments.length; i++) {        var nextSource = arguments[i];        // 参数为空,则跳过,继续下一个        if (nextSource === undefined || nextSource === null) {          continue;        }        nextSource = Object(nextSource);        // 获取改参数的所有key值,并遍历        var keysArray = Object.keys(nextSource);        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {          var nextKey = keysArray[nextIndex];          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);          // 如果不为空且可枚举,则直接浅拷贝赋值          if (desc !== undefined && desc.enumerable) {            to[nextKey] = nextSource[nextKey];          }        }      }      return to;    }  });}

上面的代码可以直接说明它只对顶层属性做了赋值,完全没有继续做递归之类的把所有下一层的属性做深拷贝。

小结一下

Object.assign() 只是一级属性复制,比浅拷贝多深拷贝了一层而已。用的时候,还是要注意这个问题的。

附:发现一个可以简单实现深拷贝的方法,当然,有一定限制,如下:

const obj1 = JSON.parse(JSON.stringify(obj));

思路就是将一个对象转成json字符串,然后又将字符串转回对象。

细说一下Object.assign()

Object.assign()

  • Object.assign() 第一个参数是目标对象,后面的都是源对象。 Object.assign (target, source1,source2, source3, …);

  • 如果源对像与目标对象有相同的属性名,或源对象中有相同的属性名,后面的会覆盖前边的值 。

  • 如果参数传入的不是Object,会转成Object

  • null和undefined 不能作为参数传入,因为null和undefined 不能转成Object

  • 如果发生的值是一个对象,Object.assign的处理方法是直接替换,而不是添加。 如下面的 a 和 b

  • 可以为类添加方法

const obj1  = {name:'小明', age:'18',education:'undergraduate'}    const obj2 = {height:'180cm',hobby:'painting'}    let  obj = Object.assign({},obj1, obj2)    console.log('合并后的类:');    console.log(JSON.stringify(obj));    Object.assign(obj, obj, {height:'170cm'});    console.log('修改过height后的类:');    console.log(JSON.stringify(obj));    Object.assign(obj, {arr:{index:1, name:'类'}}, {name:'加了一个类进去'})    console.log(JSON.stringify(obj));    console.log("加一个类进去后:"+obj.arr.index);    // a. 这种修改方式,只会修改index 的值    Object.assign(obj, Object.assign(obj.arr, {index:2}))    console.log(JSON.stringify(obj));    console.log("修改类index后:"+obj.arr.index);    // b. 这种修改方式,arr只剩下index属性    // Object.assign(obj, {arr:{index:2}}, {name:'修改类的index为:2'})    // console.log(JSON.stringify(obj));    // console.log("修改类index后:"+obj.arr.index);    // Object.assign()做的是浅拷贝, 如果一个属性是新合并进来的对象,改变源对象的值,会影响合并后的值 。    let newObj  = {type:{aa:'蔬菜'}};    Object.assign(obj, newObj);    console.log("合并一个含属性type的类后:"+JSON.stringify(obj));    // c. 这种不会影响obj中的type.aa    // Object.assign(newObj, {type:{aa:'水果'}});    // d. 这种会影响obj中的type.aa    newObj.type.aa = '水果';    console.log("修改newObj中的type.aa后:"+JSON.stringify(newObj));    console.log("修改newObj中的type.aa后:"+JSON.stringify(obj));    // e. 用Object.assign合并一个数组的时候,会把数组当成一个属性名为index的类    const arr1  = [1, 2, 3, 4, 5] ;  // 在Object的眼里是这样的: arr1={0:1, 1:2, 2:3,3:4, 4:5}    const arr2 =  [8, 9, 10];        // 在Object的眼里是这样的: arr2={0:8, 1:9, 2:10}    console.log("合并后的数组为:"+Object.assign(arr1, arr2)); // 得到的结果是:8, 9, 10, 4, 5    // f. Object.assign() 为类添加方法    Object.assign(UserInfo.prototype, {      getUserName (){        return this.name;      },      getUserGender (){        return this.gender ;      }    })    let user  = new UserInfo("笑笑", '女');    console.log("userinfo中的信息为: "+ user.getUserName() +", "+user.getUserGender()); // 输出的结果为:笑笑,女

输出的结果:

ObjectAssignDemo.js:13 合并后的类:
ObjectAssignDemo.js:14 {"name":"小明","age":"18","education":"undergraduate","height":"180cm","hobby":"painting"}
ObjectAssignDemo.js:16 修改过height后的类:
ObjectAssignDemo.js:17 {"name":"小明","age":"18","education":"undergraduate","height":"170cm","hobby":"painting"}
ObjectAssignDemo.js:19 {"name":"加了一个类进去","age":"18","education":"undergraduate","height":"170cm","hobby":"painting","arr":{"index":1,"name":"类"}}
ObjectAssignDemo.js:20 加一个类进去后:1
ObjectAssignDemo.js:24 {"name":"类","age":"18","education":"undergraduate","height":"170cm","hobby":"painting","arr":{"index":2,"name":"类"},"index":2}
ObjectAssignDemo.js:25 修改类index后:2
ObjectAssignDemo.js:35 合并一个含属性type的类后:{"name":"类","age":"18","education":"undergraduate","height":"170cm","hobby":"painting","arr":{"index":2,"name":"类"},"index":2,"type":{"aa":"蔬菜"}}
ObjectAssignDemo.js:40 修改newObj中的type.aa后:{"type":{"aa":"水果"}}
ObjectAssignDemo.js:41 修改newObj中的type.aa后:{"name":"类","age":"18","education":"undergraduate","height":"170cm","hobby":"painting","arr":{"index":2,"name":"类"},"index":2,"type":{"aa":"水果"}}
ObjectAssignDemo.js:46 合并后的数组为:8,9,10,4,5
ObjectAssignDemo.js:58 userinfo中的信息为: 笑笑, 女

以上就是关于"javascript的Object.assign()怎么用"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

拷贝 属性 对象 方法 参数 结果 内容 代码 数组 水果 只是 就是 问题 面的 小明 影响 相同 两个 例子 信息 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 新华互联网科技 互联网科技网 互联网金融 科技 互联网金融 科技金融 深圳齐家互联网科技 互联网 视角下的科技创新 佰商互联网科技有限公司 汉立互联网科技有限公司联系电话 互联网科技中介 中国互联网有什么科技含量 贵州叶脉互联网科技有限公司所属行业 宝灵互联网科技有限公司 阿大互联网科技有限公司 乌苏新华互联网科技做什么的 阿里互联网科技企业 江苏苏星互联网科技有限公司 济南小医互联网科技有限公司招聘 广西科技产业互联网是什么 中国科技和美国互联网 武汉亿视互联网科技有限公司 北京路客互联网科技有限公司 关于新基建和互联网科技 汇久创客互联网科技 赫美联合互联网科技 顶级互联网科技成果有哪些 互联网科技大奖都有哪些公司 吉林省码上互联网科技电话 科技互联网行业投资研究 互联网对科技影响 数字科技和互联网金融哪个好
0