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

摘要:
注:1.对象。assign()只是一级属性副本,它只比浅层副本深一层。对象assign()方法的特点:浅层复制和对象属性合并代码如下:varnObj=object。分配解析:花括号称为目标对象,obj和obj1是源对象。consttarget=对象分配控制台。日志//编号{1}类型的目标//“对象”副本代码为空且未定义,无法转换为对象。因此,如果将它们用作目标对象,将报告错误。consttarget=对象。assignconsttar=对象。分配//Cannotconvertdundefinedornulltoolobject如果将null和undefined用作源对象,则不会报告任何错误,因为基本数据类型被包装,null和undefined将被忽略。Constarget=对象。assignconsole。log//[4,5,3]复制浅深度对象中的代码。assogin()实现浅层复制。

注意:

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)
}
复制代码

浏览器兼容性

浅谈ES6的Object.assign()浅拷贝第1张

.

免责声明:文章转载自《浅谈ES6的Object.assign()浅拷贝》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python中常用的内置函数和内置模块pyqt5树状分隔画面下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

oracle之检查点(Checkpoint)

检查点是一个数据库事件,它把修改数据从高速缓存写入磁盘,并更新控制文件和数据文件。检查点分为三类:1)局部检查点:单个实例执行数据库所有数据文件的一个检查点操作,属于此实例的全部脏缓存区写入数据文件。触发命令:svmrgrl>alter system checkpoint local;这条命令显示的触发一个局部检查点。2)全局检查点:所有实例(对应并...

Luci实现框架

1.总述 上一篇总结了uhttpd的工作方式,openwrt中利用它作为web服务器,实现客户端web页面配置功能。对于request处理方式,采用的是cgi,而所用的cgi程序就是luci,工作框架如下图所示: Client端和serv端采用cgi方式交互,uhttpd服务器的cgi方式中,fork出一个子进程,子进程利用execl替换为luci进...

高德地图获取当前屏幕中心点的经纬度

公司有个需求就是要随着屏幕的改变而载入附近的商户信息. 那么高德地图获取当前屏幕中心点的经纬度呢? 核心方法:aMap.setOnCameraChangeListener(this); 实现接口: @Overridepublic void onCameraChange(CameraPosition position) {LatLng target...

Unity3D中Mathf数学运算函数总结

引入: 看到一个案例注意到函数Mathf.SmoothDamp的使用,游戏中用于做相机的缓冲跟踪和boss直升机跟踪士兵。该函数是Unity3D中Mathf数学运算函数中的一个。一些游戏使用了smoothmove的功能,其实就是类似的效果,只是发现这个函数很容易的已经封装好了,查了官网文档发现使用起来真的非常简单。 smoothdamp,我的理解是平滑缓...

google代码风格(转)

Google C++ 风格指南 - 中文版 from http://code.google.com/p/google-styleguide/ 版本: 3.133 原作者: Benjy Weinberger Craig Silverstein Gregory Eitzmann Mark Mentovai Tashana Landray 翻译: Yul...

git提交过滤target文件 idea_IDEA GIT 忽略文件的最佳方式推荐

在intellij中忽略提交文件,分两种情况, 文件没有纳入版本管理 第一种方法 文件还没有纳入版本管理,这种通过 svn的ignore配置 version control—-local changes—-configure ignored files 忽略文件分几大类,忽略某个文件夹、忽略某类文件(正则)、忽略某个文件 文件已经纳入版本管理 如果文件已...