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

语法

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

参数

target
目标对象。
sources
源对象。

返回值

目标对象。

  1. const target = { a: 1, b: 2 };
  2. const source = { b: 4, c: 5 };
  3.  
  4. const returnedTarget = Object.assign(target, source);
  5.  
  6. console.log(target);
  7. // expected output: Object { a: 1, b: 4, c: 5 }
  8.  
  9. console.log(returnedTarget);
  10. // expected output: Object { a: 1, b: 4, c: 5 }

结果

  1. Object { a: 1, b: 4, c: 5 } 源对象也被改变
  2. > Object { a: 1, b: 4, c: 5 } 目标对象也被改变

用来给对象属性赋值  copy对象

实例:

复制一个对象

  1. const obj = { a: 1 };
  2. const copy = Object.assign({}, obj);
  3. console.log(copy); // { a: 1 }

注意:深拷贝问题 链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。

  1. let obj1 = { a: 0 , b: { c: 0}};
  2. let obj2 = Object.assign({}, obj1);
  3. console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
  4. obj1.a = 1;
  5. console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
  6. console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
  7. obj2.a = 2;
  8. console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
  9. console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}}
  10. obj2.b.c = 3;
  11. console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
  12. console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}}
  13. // Deep Clone
  14. obj1 = { a: 0 , b: { c: 0}};
  15. let obj3 = JSON.parse(JSON.stringify(obj1));
  16. obj1.a = 4;
  17. obj1.b.c = 4;
  18. console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}

合并对象

  1. const o1 = { a: 1 };
  2. const o2 = { b: 2 };
  3. const o3 = { c: 3 };
  4. const obj = Object.assign(o1, o2, o3);
  5. console.log(obj); // { a: 1, b: 2, c: 3 }
  6. console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

合并具有相同属性的对象

  1. const o1 = { a: 1, b: 1, c: 1 };
  2. const o2 = { b: 2, c: 2 };
  3. const o3 = { c: 3 };
  4. const obj = Object.assign({}, o1, o2, o3);
  5. console.log(obj); // { a: 1, b: 2, c: 3 }

属性被后续参数中具有相同属性的其他对象覆盖。

拷贝 symbol 类型的属性

  1. const o1 = { a: 1 };
  2. const o2 = { [Symbol('foo')]: 2 };
  3. const obj = Object.assign({}, o1, o2);
  4. console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
  5. Object.getOwnPropertySymbols(obj); // [Symbol(foo)]

继承属性和不可枚举属性是不能拷贝的

  1. const obj = Object.create({foo: 1}, { // foo 是个继承属性。
  2. bar: {
  3. value: 2 // bar 是个不可枚举属性。
  4. },
  5. baz: {
  6. value: 3,
  7. enumerable: true // baz 是个自身可枚举属性。
  8. }
  9. });
  10. const copy = Object.assign({}, obj);
  11. console.log(copy); // { baz: 3 }

原始类型会被包装为对象

  1. const v1 = "abc";
  2. const v2 = true;
  3. const v3 = 10;
  4. const v4 = Symbol("foo")
  5. const obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
  6. // 原始类型会被包装,null 和 undefined 会被忽略。
  7. // 注意,只有字符串的包装对象才可能有自身可枚举属性。
  8. console.log(obj); // { "0": "a", "1": "b", "2": "c" }

异常会打断后续拷贝任务

  1. const target = Object.defineProperty({}, "foo", {
  2. value: 1,
  3. writable: false
  4. }); // target 的 foo 属性是个只读属性。
  5. Object.assign(target, {bar: 2}, {foo2: 3, foo: 3, foo3: 3}, {baz: 4});
  6. // TypeError: "foo" is read-only
  7. // 注意这个异常是在拷贝第二个源对象的第二个属性时发生的。
  8. console.log(target.bar); // 2,说明第一个源对象拷贝成功了。
  9. console.log(target.foo2); // 3,说明第二个源对象的第一个属性也拷贝成功了。
  10. console.log(target.foo); // 1,只读属性不能被覆盖,所以第二个源对象的第二个属性拷贝失败了。
  11. console.log(target.foo3); // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的。
  12. console.log(target.baz); // undefined,第三个源对象更是不会被拷贝到的。

拷贝访问器

  1. const obj = {
  2. foo: 1,
  3. get bar() {
  4. return 2;
  5. }
  6. };
  7. let copy = Object.assign({}, obj);
  8. console.log(copy); // { foo: 1, bar: 2 } copy.bar的值来自obj.bar的getter函数的返回值
  9. // 下面这个函数会拷贝所有自有属性的属性描述符
  10. function completeAssign(target, ...sources) {
  11. sources.forEach(source => {
  12. let descriptors = Object.keys(source).reduce((descriptors, key) => {
  13. descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
  14. return descriptors;
  15. }, {});
  16. // Object.assign 默认也会拷贝可枚举的Symbols
  17. Object.getOwnPropertySymbols(source).forEach(sym => {
  18. let descriptor = Object.getOwnPropertyDescriptor(source, sym);
  19. if (descriptor.enumerable) {
  20. descriptors[sym] = descriptor;
  21. }
  22. });
  23. Object.defineProperties(target, descriptors);
  24. });
  25. return target;
  26. }
  27. copy = completeAssign({}, obj);
  28. console.log(copy);
  29. // { foo:1, get bar() { return 2 } }

Polyfill

polyfill不支持 symbol 属性,因为ES5 中根本没有 symbol :

  1. if (typeof Object.assign != 'function') {
  2. // Must be writable: true, enumerable: false, configurable: true
  3. Object.defineProperty(Object, "assign", {
  4. value: function assign(target, varArgs) { // .length of function is 2
  5. 'use strict';
  6. if (target == null) { // TypeError if undefined or null
  7. throw new TypeError('Cannot convert undefined or null to object');
  8. }
  9. let to = Object(target);
  10. for (var index = 1; index < arguments.length; index++) {
  11. var nextSource = arguments[index];
  12. if (nextSource != null) { // Skip over if undefined or null
  13. for (let nextKey in nextSource) {
  14. // Avoid bugs when hasOwnProperty is shadowed
  15. if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
  16. to[nextKey] = nextSource[nextKey];
  17. }
  18. }
  19. }
  20. }
  21. return to;
  22. },
  23. writable: true,
  24. configurable: true
  25. });
  26. }

规范

规范名称 规范状态 备注
ECMAScript 2015 (6th Edition, ECMA-262)
Object.assign
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
Object.assign
Draft  

浏览器兼容

Update compatibility data on GitHub

  Desktop Mobile Server
  Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Edge Mobile Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
assign Full support45 Full support12 Full support34 No supportNo Full support32 Full support9 No supportNo Full support45 Full supportYes Full support34 Full support32 Full supportYes Full support5.0 Full support4.0.0

Legend

Full support 
Full support
No support 
No support

相关链接

文档标签和贡献者

 最后编辑者: mdnwebdocs-bot, Mar 18, 2019, 4:32:16 PM
  1. Web 开发技术
  2. JavaScript
  3. JavaScript 参考文档
  4. JavaScript 标准库
  5. Object
  6. Object.assign()
相关主题
  1. JavaScript 标准库
  2. Object
  3. 属性
    1. Object.prototype
    2. Object.prototype.__count__
    3. Object.prototype.__noSuchMethod__
    4. Object.prototype.__parent__
    5. Object.prototype.__proto__
    6. Object.prototype.constructor
  4. 方法
    1. Object.assign()
    2. Object.create()
    3. Object.defineProperties()
    4. Object.defineProperty()
    5. Object.entries()
    6. Object.freeze()
    7. Object.fromEntries()
    8. Object.getNotifier()
    9. Object.getOwnPropertyDescriptor()
    10. Object.getOwnPropertyDescriptors()
    11. Object.getOwnPropertyNames()
    12. Object.getOwnPropertySymbols()
    13. Object.getPrototypeOf()
    14. Object.is()
    15. Object.isExtensible()
    16. Object.isFrozen()
    17. Object.isSealed()
    18. Object.keys()
    19. Object.observe()
    20. Object.preventExtensions()
    21. Object.prototype.__defineGetter__()
    22. Object.prototype.__defineSetter__()
    23. Object.prototype.__lookupGetter__()
    24. Object.prototype.__lookupSetter__()
    25. Object.prototype.eval()
    26. Object.prototype.hasOwnProperty()
    27. Object.prototype.isPrototypeOf()
    28. Object.prototype.propertyIsEnumerable()
    29. Object.prototype.toLocaleString()
    30. Object.prototype.toSource()
    31. Object.prototype.toString()
    32. Object.prototype.unwatch()
    33. Object.prototype.valueOf()
    34. Object.prototype.watch()
    35. Object.seal()
    36. Object.setPrototypeOf()
    37. Object.unobserve()
    38. Object.values()
  5. 继承
  6. Function
  7. 属性
    1. Function.arguments
    2. Function.arity
    3. Function.caller
    4. Function.displayName
    5. Function.length
    6. Function.prototype

es6 Object.assign(target, ...sources)的更多相关文章

  1. es6 Object.assign

    ES6 Object.assign 一.基本用法 Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target).它至少需要两个对象作为参数,第一个参数是目 ...

  2. es6 Object.assign ECMAScript 6 笔记(六) ECMAScript 6 笔记(一) react入门——慕课网笔记 jquery中动态新增的元素节点无法触发事件解决办法 响应式图像 弹窗细节 微信浏览器——返回操作 Float 的那些事 Flex布局 HTML5 data-* 自定义属性 参数传递的四种形式

    es6 Object.assign   目录 一.基本用法 二.用途 1. 为对象添加属性 2. 为对象添加方法 3. 克隆对象 4. 合并多个对象 5. 为属性指定默认值 三.浏览器支持 ES6 O ...

  3. ES6 的Object.assign(target, source_1, ···)方法与对象的扩展运算符

    一.基本概念 Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target).它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象. Ob ...

  4. [ES6] Object.assign (with defaults value object)

    function spinner(target, options = {}){ let defaults = { message: "Please wait", spinningS ...

  5. (转)es6中object.create()和object.assign()

    今天学习javascript面向对象,在学习Obejct方法时了解到create方法,偶像想起之前使用的assign方法,顺带查找一番,感觉这篇博客讲解详细,遂转载. 先简单提一下装饰器函数,许多面向 ...

  6. ES6学习--Object.assign()

    ES6提供了Object.assign(),用于合并/复制对象的属性. Object.assign(target, source_1, ..., source_n) 1. 初始化对象属性 构造器正是为 ...

  7. es6 javascript对象方法Object.assign()

    es6 javascript对象方法Object.assign() 2016年12月01日 16:42:34 阅读数:38583 1  基本用法 Object.assign方法用于对象的合并,将源对象 ...

  8. 【ES6学习笔记之】Object.assign()

    基本用法 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). const target = { a: 1 }; const sou ...

  9. [转]理解Object.assign

    本节内容我们继续探讨关于ES2015的一些新的内容,Object.assign函数的使用,使用该函数我们可以快速的复制一个或者多个对象到目标对象中,本文内容涉及es6,es7相关的对象复制的内容,以及 ...

随机推荐

  1. SAS中的聚类分析方法总结

    SAS中的聚类分析方法总结 说起聚类分析,相信很多人并不陌生.这篇原创博客我想简单说一下我所理解的聚类分析,欢迎各位高手不吝赐教和拍砖. 按照正常的思路,我大概会说如下几个问题: 1.     什么是 ...

  2. Python新手最容易犯的十大错误

    1. 忘记写冒号 在 if.elif.else.for.while.class.def 语句后面忘记添加“:” if spam == 42 print('Hello!') 2. 误用 “=” 做等值比 ...

  3. IOS CocoaPods的用法

    自从有了CocoaPods以后,这些繁杂的工作就不再需要我们亲力亲为了,只需要我们做好少量的配置工作,CocoaPods会为我们做好一切   一.什么是CocoaPods 1.为什么需要CocoaPo ...

  4. LeetCode.1021-删除最外面的括号(Remove Outermost Parentheses)

    这是小川的第380次更新,第408篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第242题(顺位题号是1021).有效的括号字符串为空(""),&qu ...

  5. Altera DDR2 IP核学习总结2-----------DDR2 IP核的生成

    打开IP核工具,然后选择Verilog HDL选项,填写路径,写入文件名DDR2_IP.V,点击next PLL reference clock frequency填入板子晶振的频率50MHZ,这里设 ...

  6. qt 两种按钮点击事件应用

    1.传统connect 例如: connect(ui->findPushBtn,SIGNAL(clicked()),this,SLOT(find())); 参数1:事件UI 参数2:点击系统函数 ...

  7. jsp运行环境的安装和配置

    1.JDK的安装和配置 1)下载jdk,我下载的是1-jdk-6u26-windows-i586.exe,放在D:\StudySystem\JavaWeb\jdk目录下. 2)安装jdk,直接你下载的 ...

  8. Magic Potion(网络流)

    原题链接 2018南京的铜牌题,听说学长他们上来就A了,我这个图论选手也就上手做了做,结果一言难尽...... 发此篇博客希望自己能牢记自己的菜... 本题大意:有n个heros和m个monsters ...

  9. Java中的模板设计模式,太实用了!

    顾名思义,模板设计模式就是将许多公用的常用的代码封装成一个模板,我们只需要实现不同的业务需求的代码,然后和模板组合在一起,那么就得到完整的逻辑. 在我们的日常开发中,常用的模板模式有两种实现方式:继承 ...

  10. MyBatis按时间排序

    测试代码 ActivityReadExample readExample = new ActivityReadExample(); readExample.setOrderByClause(" ...