只能拷贝对象的第一层的相关拷贝方法(浅拷贝,第二层还是指向原来的地址)
只能拷贝对象的第一层,如果对象中的属性也是对象的话(第二层),第二层指向原来的地址
...延展操作符
代码:
function deep_clone_point () {
const obj1 = {
a: 'a',
b: 'ab',
c: {
cc: 'cc',
cd: 'cd'
}
}
const obj_clone = {...obj1}
obj_clone['a'] = 1;
obj_clone['c']['cc'] = 'ccc'
console.log('=======>obj1',obj1)
console.log('=======>obj_clone',obj_clone)
}
结果:
for in 循环遍历对象
代码:
function deep_clone_for () {
const obj1 = {
a: 'a',
b: 'ab',
c: {
cc: 'cc',
cd: 'cd'
}
}
let obj_clone = {}
for (const key in obj1) {
obj_clone[key] = obj1[key]
}
obj_clone['a'] = 'aa';
obj_clone['c']['cc'] = 'cccc'
console.log('=======>obj1',obj1)
console.log('=======>obj_clone',obj_clone)
}
结果:
Object.assign() 对象的合并
代码:
function deep_clone_assign () {
const obj1 = {
a: 'a',
b: 'ab',
c: {
cc: 'cc',
cd: 'cd'
}
}
var obj_clone = Object.assign({},obj1);
obj_clone['a'] = 'clone';
obj_clone['c']['cc'] = 'cloned'
console.log('=======>obj1',obj1)
console.log('=======>obj_clone',obj_clone)
}
结果:
slice方法(数组的方法)
可以看到,第二层的无论是obj还是arr,都是指向原来的地址
代码:
function deep_clone_slice () {
const array1 = ['a', 'b', {c: 'c'}, ['d','e']]
const arrat_clone = array1.slice()
arrat_clone[0] = 'clone';
arrat_clone[2]['c'] = 'cloned'
arrat_clone[3][0] = 'cloned_two'
console.log('=======>array1',array1)
console.log('=======>arrat_clone',arrat_clone)
}
结果:
concat方法
代码:
function deep_clone_concat () {
const array1 = ['a', 'b', {c: 'c'}, ['d','e']]
const array_clone = array1.concat()
array_clone[0] = 'clone';
array_clone[2]['c'] = 'cloned'
array_clone[3][0] = 'cloned_two'
console.log('=======>array1',array1)
console.log('=======>arrat_clone',array_clone)
}
结果:
递归
深拷贝,是拷贝对象各个层级的属性
代码:
function deep_clone_digui(obj) {
let obj_clone = Array.isArray(obj) ? [] : {};
if(obj && typeof obj === "object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判断obj子元素是否为对象,如果是,递归复制
if(obj[key] && typeof obj[key] === "object"){
// 这里我们的递归使用一个js的调用函数自己的api
obj_clone[key] = arguments.callee(obj[key]);
}else{
//如果不是,简单复制
obj_clone[key] = obj[key];
}
}
}
}
return obj_clone;
}
function deep_clone_digui_test() {
const array1 = ['a', 'b', {c: 'c'}, ['d','e']]
const array_clone = deep_clone_digui(array1)
array_clone[0] = 'clone';
array_clone[2]['c'] = 'cloned'
array_clone[3][0] = 'cloned_two'
console.log('=======>array1',array1)
console.log('=======>arrat_clone',array_clone)
}
结果:
Json.stringify和Json.parse
当值为undefined、function、symbol、RegExp会在转换过程中被忽略,所以它有局限性
代码:
function deep_clone_json () {
const obj1 = {
a: 'a',
b: 'ab',
c: {
cc: 'cc',
cd: 'cd'
}
}
const obj_clone = JSON.stringify(obj1)
const obj_clone_parse =JSON.parse(obj_clone)
obj_clone_parse['a'] = 1;
obj_clone_parse['c']['cc'] = 'ccc'
console.log('=======>obj_clone',obj_clone)
console.log('=======>obj_clone_parse',obj_clone_parse)
}
结果:
函数库lodash的_.cloneDeep方法
代码:
function deep_clone_loadsh () {
const _ = require('lodash')
const obj1 = {
a: 'a',
b: 'ab',
c: {
cc: 'cc',
cd: 'cd'
}
}
const obj_clone = _.cloneDeep(obj1)
console.log('=======>obj_clone',obj_clone === obj1); //false
obj_clone['a'] = 1;
obj_clone['c']['cc'] = 'ccc'
console.log('=======>obj1',obj1)
console.log('=======>obj_clone',obj_clone)
}
结果:
通过JQuery的extend方法实现深拷贝
$.extend( [deep ], target, object1 [, objectN ] )
- deep
表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
- target
Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
- object1 objectN
可选。 Object类型 第一个以及第N个被合并的对象。
代码:
function deep_clone_jq () {
const _ = require('jquery')
const obj1 = {
a: 'a',
b: 'ab',
c: {
cc: 'cc',
cd: 'cd'
}
}
const obj_clone = $.extend(true, {}, obj1);
console.log('=======>obj_clone',obj_clone === obj1); //false
obj_clone['a'] = 1;
obj_clone['c']['cc'] = 'ccc'
console.log('=======>obj1',obj1)
console.log('=======>obj_clone',obj_clone)
}