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

语法

Object.assign(target, ...sources)

参数

target
目标对象。
sources
源对象。

返回值

目标对象。

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

结果

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

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

实例:

复制一个对象

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

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

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

let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj1.a = 1;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}} obj2.a = 2;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 0}} obj2.b.c = 3;
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 3}}
console.log(JSON.stringify(obj2)); // { a: 2, b: { c: 3}} // Deep Clone
obj1 = { a: 0 , b: { c: 0}};
let obj3 = JSON.parse(JSON.stringify(obj1));
obj1.a = 4;
obj1.b.c = 4;
console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}

合并对象

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

合并具有相同属性的对象

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

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

拷贝 symbol 类型的属性

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

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

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

原始类型会被包装为对象

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

异常会打断后续拷贝任务

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

拷贝访问器

const obj = {
foo: 1,
get bar() {
return 2;
}
}; let copy = Object.assign({}, obj);
console.log(copy); // { foo: 1, bar: 2 } copy.bar的值来自obj.bar的getter函数的返回值 // 下面这个函数会拷贝所有自有属性的属性描述符
function completeAssign(target, ...sources) {
sources.forEach(source => {
let descriptors = Object.keys(source).reduce((descriptors, key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {}); // Object.assign 默认也会拷贝可枚举的Symbols
Object.getOwnPropertySymbols(source).forEach(sym => {
let descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(target, descriptors);
});
return target;
} copy = completeAssign({}, obj);
console.log(copy);
// { foo:1, get bar() { return 2 } }

Polyfill

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

if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
} let to = Object(target); for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index]; if (nextSource != null) { // Skip over if undefined or null
for (let nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}

规范

规范名称 规范状态 备注
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. 微信小程序前端支付

    原文地址 //index.js Page({ data: { }, //点击支付按钮进行支付 payclick: function () { var t = this; wx.login({ //获取 ...

  2. Unity3D 旋转

    Unity有两种设置物体旋转的方式,一种时用Rotate()函数来旋转,另一种时直接构造目标Quaternion来直接赋予rotation. 好吧,不知到写什么,各种旋转和unity2D差不多.在国内 ...

  3. 【Deep Learning Nanodegree Foundation笔记】第 5 课:Logistic Regression

    Learn about linear regression and logistic regression models. These simple machine learning models a ...

  4. kettle 连接 mysql8.0 报错的解决办法 org.pentaho.di.core.exception.KettleDatabaseException: Error occurred while trying to connect to the database Error connecting to database: (using class org.gjt.mm.mysql.

    1.下载 mysql8.0 驱动放到 如下目录中 mysql8.0以上的驱动下载链接:mysql-connet-8.0.13 2.配置你连接的数据库 找到如下文件打开编辑 连接信息:下面是我本地的配置 ...

  5. IF-ELSE嵌套练习

    一,1,编写程序,由键盘输入三个整数分别存入变量num1,num2,num3中,对它们进行排序,使用if-else结构,并按从小到大的顺序输出: package practice; import ja ...

  6. Leetcode 35.搜索插入位置 By Python

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...

  7. Editor placeholder in source code错误

    When you insert code via autocompletion (or via a code snippet, sometimes), there may be placeholder ...

  8. Go语言中byte类型和rune类型(五)

    本篇内容本来准备在上一篇写的,想了想还是拆开写. go语言中字符串需要使用用双引号,而单引号用来表示单个的字符,字符也是组成字符串的元素.go语言的字符有两种: uint8类型,或者叫 byte 型, ...

  9. java使用face++简单实现人脸识别注册登录

    java使用face++简单实现人脸识别注册登录 前言 人脸识别,好高大上!!! 理解之后很简单. 支付宝使用的就是face++, 至于face++账号信息,apikey…..,本文不做讲述,网上很多 ...

  10. MyBatis按时间排序

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