理解Object.assign

孤人 提交于 2019-12-01 15:39:41

Object.assign()方法用于从一个或多个源对象(sources)中拷贝所有可枚举的自有属性到目标对象(target),并返回目标对象。拷贝过程中将调用源对象的getter方法,并在target对象上使用setter方法实现目标对象的拷贝。

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

不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。

原文:Both String and Symbol properties are copied.

String和Symbol类型都可被直接分配。

1234
function (origin) {	let originProto = Object.getPrototypeOf(origin);    return Object.assign(Object.create(originProto), origin);}

注意:如果属性是只读的,那将会抛出异常,目标对象将会停止改变(而之前的改变会保留)。但是对于null或者undefind会直接忽略。

简单克隆对象

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

合并对象

123456
var a = {x: 1};var b = {y: 2};var c = {x: 4, z: 3};var obj = Object.assign(a, b, c);console.log(obj); //Object {x: 4, y: 2, z: 3}

拷贝Symbol属性

12345
var a = {x: 1};var b = {[Symbol('y')]: 2};var obj = Object.assign(a, b);console.log(obj); //Object {x: 1, Symbol(y): 2}

继承的属性和不可枚举的属性不会被拷贝

1234567891011121314
var obj = Object.create({foo: 1}, //继承的对象, obj.__proto__ == {foo: 1}	{		a: { //不可枚举的			value: 2		},		b: {			value: 3,			enumerable: true //可枚举的		}	});var copy = Object.assign({}, obj);console.log(copy); //Object {b: 3}

字符串会被转成object

12345678910111213
var str = 'hejx';var obj = Object.assign({}, str);console.log(obj); //Object {0: "h", 1: "e", 2: "j", 3: "x"}var a = "123";var b = false;var c = 123;var d = Symbol('sy');var e = Object.assign({}, a, b, c, d, null, undefined);//null和undefined会被忽略,在这里只有a(字符串)可以被枚举并被转成对象,如果存在2个字符串,将会报错console.log(e); //Object {0: "1", 1: "2", 2: "3"}

只读属性不能被拷贝

12345678910111213
var target = Object.defineProperty({}, 'foo', {	value: 1, 	writable: f 大专栏  理解Object.assignalse}); // target.foo是只读属性Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 });// 这里会抛出异常,但是在错误之前,目标对象的部分属性已经被改变或者新增,而后续的将不会再进行拷贝console.log(target.bar);  // 2console.log(target.foo2); // 3console.log(target.foo);  // 1console.log(target.foo3); // undefinedconsole.log(target.baz);  // undefined

拷贝属性的赋值器(setter)和取值器(getter)

123456789101112
var obj = {	a: 1,	get b(){		return 2;	},	someMethod(){ //同样会被拷贝,可以用于为对象添加方法		//someMethod	}};var copy = Object.assign({}, obj);console.log(copy); // Object {a: 1, b: 2, someMethod: function(){}}

es5版本的Object.assign

不支持Symbol属性,因为es5压根没有Symbol

1234567891011121314151617181920212223
if (typeof Object.assign != 'function') { //判断是否支持  (function () {    Object.assign = function (target) {;      if (target === undefined || target === null) {        throw new TypeError('Cannot convert undefined or null to object');      }      var output = Object(target);      for (var index = 1; index < arguments.length; index++) {        var source = arguments[index];        if (source !== undefined && source !== null) {          for (var nextKey in source) {            if (source.hasOwnProperty(nextKey)) { //判断一个属性是定义在对象本身而不是继承自原型链              output[nextKey] = source[nextKey];            }          }        }      }      return output; //最终输出    };  })();}

不支持深度拷贝

1234
var target = { a: { b: 'c', d: 'e' } }var source = { a: { b: 'hello' } }Object.assign(target, source)// { a: { b: 'hello' } }

深度拷贝

拷贝数组

1234
var arr = [1, 2, 3]; //会被当成对象var str = "4567";var copy = Object.assign({}, arr, str);console.log(copy); // Object {0: "4", 1: "5", 2: "6", 3: "7"}

兼容性

属于es6规范,然而兼容性并不好,pc端除了ie,其他都支持。移动端目前就Firefox Mobile 支持。

文献

摘自developer.mozilla.org

es6.ruanyifeng.com

ES2015系列(二) 理解Object.assign

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!