赞
踩
1、MDN 文档已详细介绍 Object.assign()用法:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
- Object.assign
-
- 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
- 1
-
- <script>
- let obj1 = {name:'山东',id:1,city:{name:'青岛',cityId:'2'}};
- let obj2 = Object.assign(obj1);
- obj2.city.name = '济南';
- obj2.city.cityId = 3;
- console.log(obj1); //它将返回目标对象
-
- </script>
- Object.assign(target, ...sources)
-
- target:目标对象
-
- sources:源对象
-
- 返回值:目标对象
- //2、如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。
-
- let obj1 = {name:'山东',id:1};
- let obj2 = {name:'青岛',id:2};
- let obj3 = Object.assign(obj1,obj2);
- console.log(obj1,obj3); //后面的源对象的属性将类似地覆盖前面的源对象的属性。
- //3、由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
-
- Object.assign(undefined) // 报错
- Object.assign(null) // 报错
- //4、注意:Object.assign 不会在那些source对象值为 null 或 undefined 的时候抛出错误
-
- let obj = {id: 1};
- Object.assign(obj, undefined) === obj // true
- Object.assign(obj, null) === obj // true
-
-
- 如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。
- //5、 其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。(数值和布尔值都会被忽略。这是因为只有字符串的包装对象,会产生可枚举属性。)
-
- const a = '山东';
- const b = true;
- const c = 10;
- const obj = Object.assign({}, a, b, c);
- console.log(obj);
- // 6、拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)
-
- const ccc = Object.assign({b: 'c'},
- Object.defineProperty({}, 'invisible', {
- enumerable: false,
- value: 'hello'
- })
- )
- console.log(ccc)
- // 7、 属性名为 Symbol 值的属性,也会被Object.assign拷贝。
-
- const ccc = Object.assign({b: 'c'},{ [Symbol('d')]: 'e' })
-
- console.log(ccc)
2、浅拷贝:只针对Object和Array这样的对象数据类型
- // 浅拷贝的实现方式
-
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>浅/深拷贝</title>
- </head>
- <body>
-
- </body>
- <script>
- // 1、直接复制一个变量
-
- let obj1 = {name:'山东',id:1,city:{name:'青岛',cityId:'2'}};
- let obj2 = obj1;
- obj2.city.name = '济南';
- obj2.city.cityId = 3;
- console.log(obj1, obj2); // 修改复制的对象会影响原对象
-
- </script>
- </html>
- // 2、Object.assign() 第一条已介绍
-
- let obj1 = {name:'山东',id:1,city:{name:'青岛',cityId:'2'}};
- let obj2 = Object.assign(obj1);
- obj2.city.name = '济南';
- obj2.city.cityId = 3;
- console.log(obj1);
- // 3、Array.prototype.concat() 注意: 修改新对象会改到原对象:
-
- let arr = [1, 2, {
- name: '山东'
- }];
- let arr2 = arr.concat();
- arr[0] = 8;
- arr2[1] = '这是和arr1的区别';
- arr2[2].name = '山西';
- console.log(arr,arr2);
-
-
-
- var arr1 = ["1","2","3"];
- var arr2 = arr1.concat();
- arr2[1] = "9";
- console.log(arr1,arr2); //["1","2","3"] ["1","9","3"];
- // 4、Array.prototype.slice() 注意:修改新对象会改到原对象
-
- let arr = [1, 2, {
- name: ' 山东'
- }];
- let arr3 = arr.slice();
- arr3[2].name = '山西'
- console.log(arr,arr3);
- //补充
-
- 关于Array的slice和concat方法的补充说明:Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。
-
-
- 如果该元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变
-
-
- 对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组
-
3、深拷贝
- // 深拷贝
-
- // 1、JSON.parse(JSON.stringify())
-
- let arr = [1, 2, {
- name: '山东'
- }];
- let arr3 = JSON.parse(JSON.stringify(arr))
- arr3[1] = 6;
- arr3[2].name = '山西';
- console.log(arr,arr3);
-
- //原理:首先用JSON.stringify()将对象转化成JSON字符串,再用JSON。parse()将字符串解析成对象。
- 这样新的对象就会产生。而且对象会开辟新的栈。实现了深拷贝。
-
-
- // 注意:这种方法虽然可以实现数组或者对象的深拷贝,但是不能处理函数
-
- let arr = [1, 2, {
- name: '山东'
- },function add() {
- }];
- let arr3 = JSON.parse(JSON.stringify(arr))
- arr3[1] = 6;
- arr3[2].name = '山西';
- console.log(arr,arr3);
-
- // 因为JSON.stringify()方法是将一个对象或者数组转化成一个JSON字符串,不能接收函数
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。