浅谈ES6的Object.assign()浅拷贝

注意:

1、Object.assign() 只是一级属性复制,比浅拷贝多深拷贝了一层而已。用的时候,还是要注意这个问题的。
2、简单实现深拷贝的方法,当然,有一定限制,如下:JSON.parse(JSON.stringify());思路就是将一个对象转成json字符串,然后又将字符串转回对象。

Object.assign()方法

  特点:浅拷贝、对象属性的合并

  代码如下:

var nObj = Object.assign({},obj,obj1);

解析:花括号叫目标对象,后面的obj、obj1是源对象。对象合并是指:将源对象里面的属性添加到目标对象中去,若两者的属性名有冲突,后面的将会覆盖前面的

  

简介

Object.assign()方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象,它将返回目标对象。这里有两点需要注意:1、该方法复制的是可枚举的属性的值,不可枚举的属性不会处理。2、它返回的是一个对象。

语法

Object.assign(target,...sources)
复制代码

基本用法

合并对象

const target = { a: 1 }
const source1 = { b: 2 }
const source2 = { c: 3 }
Object.assign(target, source1, source2)
console.log(target)
// {a: 1, b: 2, c: 3}
复制代码

注意:如果目标对象与源对象的属性具有相同的键,或者多个源对象的属性具有相同的键,则后面对象的属性会覆盖前面对象的属性。

const target = { a: 1, b: 1 }
const source1 = { b: 2, c: 2 }
const source2 = { c: 3 }
Object.assign(target, source1, source2)
console.log(target)
// {a: 1, b: 2, c: 3}
复制代码

如果只传入了一个参数,则该方法会直接返回该参数。

const target = { a: 1 }
Object.assign(target)
console.log(target)
// {a: 1}
console.log(Object.assign(target) === target)
// true
复制代码

如果传入的参数不是对象,原始类型会被包装为对象。

const target = Object.assign(1)
console.log(target)
// Number {1}
typeof target
// "object"
复制代码

null和undefined无法被转为对象,所以如果把它们两个作为目标对象则会报错。

const target = Object.assign(null)
const tar = Object.assign(undefined)
// Cannot convert undefined or null to object
复制代码

如果null和undefined作为源对象,则不会报错,因为基本数据类型被包装,null和undefined会被忽略。

const target = Object.assign({a:1}, null)
const tar = Object.assign({a:1}, undefined)
// {a:1}
const target1 = Object.assign(1, null)
// Number {1}
复制代码

如果null和undefined作为源对象中的属性值,则它们不会被忽略

const target = Object.assign({ a: 1 }, { b: null }, { c: undefined })
console.log(target)
// {a: 1, b: null, c: undefined}
复制代码

拷贝

复制一个对象

const target = Object.assign({}, { a: 1 })
console.log(target)
// {a: 1}
复制代码

拷贝symbol类型的属性

const target = Object.assign({}, { a: 1 }, { [Symbol(‘foo‘)]: 2 })
console.log(target)
// {a: 1, Symbol(foo): 2}
复制代码

拷贝的属性是有限制的,继承属性和不可枚举属性无法被拷贝。

const obj = Object.defineProperty({}, ‘a‘, {
  enumerable: false,
  value: 1
})
console.log(obj)
// {a: 1}
const target = Object.assign({b: 2}, obj)
console.log(target)
// {b: 2}
复制代码

现在把a属性变成可枚举的属性。

const obj = Object.defineProperty({}, ‘a‘, {
  enumerable: true,
  value: 1
})
console.log(obj)
// {a: 1}
const target = Object.assign({b: 2}, obj)
console.log(target)
// {b: 2, a: 1}
复制代码

接下来再看看基本数据类型的可枚举性。

注意:首先基本数据类型会被包装成对象,null和undefined会被忽略。其次只有字符串的包装对象才可能有自身可枚举属性。

const v1 = "abc"
const v2 = true
const v3 = 10
const v4 = Symbol("foo")
const target = Object.assign({}, v1, null, v2, undefined, v3, v4)
console.log(target)
// {0: "a", 1: "b", 2: "c"}
复制代码

拷贝一个数组。该方法会把数组视为对象,同时在拷贝的时候通过位置来进行覆盖。

const target = Object.assign([1,2,3],[4,5])
console.log(target)
// [4, 5, 3]
复制代码

深浅拷贝

Object.assgin()实现的是浅拷贝。如果源对象中的某个属性的值也是对象,那么目标对象拷贝得到的是这个对象的引用,一旦这个对象发生改变,那么拷贝后的目标对象也做相应的改变。

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}}
obj1.b.c = 3
console.log(JSON.stringify(obj1))
// {"a":1,"b":{"c":3}}
console.log(JSON.stringify(obj2))
// {"a":0,"b":{"c":3}}
复制代码

至于深浅拷贝的区别以及如何实现的问题,会在之后的文章中详细说明。

常见用途

为对象添加属性

class Person {
  constructor(x, y) {
    Object.assign(this, {x, y})
  }
}
复制代码

为对象添加方法

Object.assign(someClass.prototype, {
  foo(x, y){
    ....
  }
})
复制代码

合并多个对象

Object.assign(target, ...sources)
复制代码

复制一个对象

const target = Object.assign({}, { a: 1 })
console.log(target)
// {a: 1}
复制代码

为属性指定默认值

const DEFAULT_VALUE = {
  name: ‘Joe‘,
  age: ‘27‘
}
function foo(options) {
  return Object.assign({}, DEFAULT_VALUE, options)
}
复制代码

浏览器兼容性

.

原文地址:https://www.cnblogs.com/jianxian/p/12650455.html

时间: 2024-08-06 20:25:03

浅谈ES6的Object.assign()浅拷贝的相关文章

浅谈ES6原生Promise

浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游荡在JavaScript世界. 正所谓: 世界本没有回调,写的人多了,也就有了})})})})}). Promise的兴起,是因为异步方法调用中,往往会出现回调函数一环扣一环的情况.这种情况导致了回调金字塔问题的出现.不仅代码写起来费劲又不美观,而且问题复杂的时候,阅读代码的人也难以理解. 举例如下

ES6之Object.assign()详解

译者按: 这篇博客将介绍ES6新增的Object.assign()方法. 原文: ECMAScript 6: merging objects via Object.assign() 译者: Fundebug 为了保证可读性,本文采用意译而非直译.另外,本文版权归原作者所有,翻译仅用于学习. 将A对象的属性复制给B对象,这是JavaScript编程中很常见的操作.这篇博客将介绍ES6的Object.assign()属性,可以用于对象复制. 在JavaScript生态系统中,对象复制有另外一个术语:

ES6中Object.assign() 方法

1. 对象合并Object.assign 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象上.如下代码演示: var target = {a: 0}; var source1 = {b: 1}; var source2 = {c: 2}; Object.assign(target, source1, source2); console.log(target); // 输出 {a: 0, b: 1, c: 2} 1-1 如果目标对象与源对象有同名属性,或多个源对象有同名

ES6的Object.assign()基本用法

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). 例如: const target = {a:1}, const source1 = {b:2} const source2 = {c:3}; Object.assign(target, source1,source2); target   // {a:1,b:2,c:3} Object.assign  方法的第一个参数是目标对象,后面的参数都是源对象. 注意:如果目标对象与源

ES6中Object.assign()和Object.create()

Object.assign() 语法:Object.assing(target,…sources) 一.合并对象 const first = { name: "Bob" }; const last = { lastName: "Smith" }; let person = Object.assign(first, last); console.log(person);/*{ name: 'Bob', lastName: 'Smith' }*/ 二.克隆对象 cons

纯原生仿ES6的Object.assign,实现深度合并对象

源码: function isObj(x){ var type = typeof x; return x !== null && (type === 'object' || type === 'function'); } var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(va

浅谈js最基础的 浅拷贝和 深拷贝

1.浅拷贝 就是一个对象的 值类型的复制 var dog = { name : '小黄', // bark : function(){ // console.log('汪汪汪!') // }, son :{ name: '小小黄' } } var dog1 = {} for(var k in dog){ dog1[k] = dog[k]; } dog1.name = "小黑" console.log(dog.name)/* 小黄*/ console.log(dog1.name) /*小

由jtable浅谈vector<vector<Object>>的用法(转自a718515028的专栏)

以前只用过vector<Object>  ,但是在做从数据库导出数据放到jtable中时,发现还有个vector<vector<Object>>的用法. 先说jtable和DefaultTableModel jtable本身是可以显示一张列表,但是不能按钮监听的增加正行数据. jtable中没有addRow(Object[] rowData) 或者addRow(Vector rowData) ,方法. 但是jtable中有一个构造方法,JTable(TableModel

浅谈ES6

ECMAScript6简介 ECMAScript6(简称ES6)是JavaScript语言的下一代标准,已于2015年6月正式发布.ES6是在2015年发布的,所以又称ECMAScript2015. 一.ES6声明变量的六种方法 let命令 1.let命令用于声明变量,但是所声明的变量只有在let命令所在的代码块内有效. 2.let不存在变量提升,所以变量一定要在声明后使用,否则报错. 3.只要块级作用域内存在let命令,它所声明的变量就绑定在这个区域,不再受外部的影响.成为"暂时性死区&quo