关键词
- 克隆;
- 复制;
- 浅拷贝;
- 深拷贝;
浅拷贝
- slice();
- concat();
- 扩展运算符;
- Object.assign()
/ slice() /
slice()方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不`会被改变。
示例1
var arr = [0,1,2,3,4]; const newArr= arr.slice(); console.log(newArr)//[ 0, 1, 2, 3, 4 ] newArr[0]=111; console.log(arr,newArr) //[ 0, 1, 2, 3, 4 ] [ 111, 1, 2, 3, 4 ]
示例2
var arr = [{name:'allen',age:12}]; const newArr= arr.slice(); console.log(newArr) newArr[0].name='halen'; console.log(arr,newArr) //[ { name: 'halen', age: 12 } ] [ { name: 'halen', age: 12 } ] // 原本的数组被改变了————浅拷贝
/ concat() /
concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
示例1
var arr = [0,1,2,3,4]; const newArr= arr.concat([]); console.log(newArr)//[ 0, 1, 2, 3, 4 ] newArr[0]=111; console.log(arr,newArr) //[ 0, 1, 2, 3, 4 ] [ 111, 1, 2, 3, 4 ]
示例2
var arr = [{name:'allen',age:12}]; const newArr= arr.concat(); console.log(newArr) newArr[0].name='halen'; newArr[0].age=22; console.log(arr,newArr) //[ { name: 'halen', age: 22 } ] [ { name: 'halen', age: 22 } ] // 原本的数组被改变了————浅拷贝
/ 扩展运算符 /
示例1
let arr = [{name:'allen',age:12}];let newArr = [...arr];console.log(arr,newArr);//[ { name: 'allen', age: 12 } ] [ { name: 'allen', age: 12 } ]newArr[0].age=22,newArr[0].name='hallen';console.log(arr,newArr)//[ { name: 'hallen', age: 22 } ] [ { name: 'hallen', age: 22 } ]//浅拷贝
❗️注意
- splice()————删除、增加数组元素;会改变原本的数组;
深拷贝
1.JSON.stringify()+JSON.parse();
/ JSON.stringify()+JSON.parse() /
示例1
var arr = [{name:'allen',age:12,class:undefined},function speak(){console.log('speak')}];const newArr= JSON.parse(JSON.stringify(arr));console.log(newArr) //[ { name: 'allen', age: 12 }, null ]newArr[0].name='halen';newArr[0].age=22;console.log(arr,newArr) //[ { name: 'allen', age: 12, class: undefined }, [Function: speak] ] [ { name: 'halen', age: 22 }, null ]// 函数变成了null,undefined直接‘消失’了。
示例2
// 函数和undefinedvar arr = [{name:'allen',age:12,show(){console.log('aa')},class:undefined}];const newArr= JSON.parse(JSON.stringify(arr));console.log(arr,newArr) //[ { name: 'allen', age: 12 } ]newArr[0].name='halen';newArr[0].age=22;console.log(arr,newArr) //[{ name: 'allen', age: 12, show: [Function: show], class: undefined }] [ { name: 'halen', age: 22 } ]// 无法克隆对象中的函数和undefined
☀️*这是因为:
JSON.stringify() 将值转换为相应的JSON格式:
转换值如果有 toJSON() 方法,该方法定义什么值将被序列化。非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined).对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。Date 日期调用了 toJSON() 将其转换为了 string 字符串(同Date.toISOString()),因此会被当做字符串处理。NaN 和 Infinity 格式的数值及 null 都会被当做 null。其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性
注意
- 用JSON.stringify + JSON.parse()进行数组深拷贝时,要注意函数,undefined,Symbol的问题;
- Object.assign()只会拷贝自身的且可枚举的属性到目标中;
- 元素不多且不复杂可循环复制;