工作版本:
// JSON.parse(JSON.stringify) :深拷贝
var origin_data = { a: 1, b: 2, c: [1, 2, 3] }
var copy_data = JSON.parse(JSON.stringify(origin_data))
乞丐面试版:
var p = {
"id":"007",
"name":"刘德华",
"wife": {
"id":"008",
"name":"刘德的妻子",
"address": {
"city":"北京",
"area":"海淀区"
}
}
}
//写函数
function copyObj(obj) {
let newObj = {};
for (let key in obj) {
if (typeof obj[key] == 'object') {
newObj[key] = copyObj(obj[key]);//如:key是wife,引用类型,那就递归
} else {
newObj[key] = obj[key];//基本类型,直接赋值
}
}
return newObj;
}
let pNew = copyObj(p);
正常版本:
let arr = [5, 4, 9, 8]
let obj1 = {
name: 'xxx',
sex: '男',
like: ['红色', '蓝色'],
book: {
title: 'js程序',
price: '88'
}
}
function deepClone(obj) {
//查看要拷贝的对象是数组还是对象,如果数组创建空数组,是对象创建空对象
let newObj = obj instanceof Array ? [] : {}
for (let k in obj) {
//K属性名 obj[k]值
//判断当前每个元素是否是对象或者数组
//如果还是对象,继续递归拷贝
//是值,直接添加到新创建的对象或者数组里
if (typeof obj[k] === 'object') {
//递归拷贝完 放入到新对象的属性
newObj[k] = deepClone(obj[k])
} else {
//否则是值, 直接添加到新建的 newObj中
newObj[k] = obj[k]
}
}
//返回新对象
return newObj
}
var obj2 = deepClone(obj1)
obj2.like.push('紫色')
obj2.book.price = 999
console.log(obj1);
console.log(obj2);
豪华版本:
<script>
let obj =
{
uname: '小妲己',
age: 18,
hobby: ['打野', '蹲草丛', '魅惑'],
team: ['坤坤', '波波', '迪迪', '宏宏'],
company: {
add1: '科技二路',
add2: '科技六路',
add3: '立人科技',
add4: ['a座', 'b座', 'c座']
},
un: undefined,
nu: null,
show: function () {
console.log('秀儿');
},
reg: /^[0-9]$/
}
// 深拷贝实现思路:遍历源数据,跟据属性值分为3种情况:1. 如果是对象或者数组,就继续遍历,直到得到基本类型;2. 如果是函数,就调用bind方法复制一个新的方法即可; 3. 如果是基本数据类型,就直接赋值即可
/*
分析:
=> 1. 拷贝的源数据可以是数组,也可以是对象, 需要使用for...in遍历
=> 2. 判断数据类型的方法:Object.prototype.toString.call()
=> 3. 将数据类型判断的方法封装成函数:1. 判断是否是 a数组, b对象, c方法
*/
// 1. 封装判断数据类型的函数
function getType(data) {
return Object.prototype.toString.call(data)
}
// 2. 封装对数组的判断
function isArray(data) {
return getType(data) === '[object Array]'
}
// 3. 封装对对象的判断
function isObj(data) {
return getType(data) === '[object Object]'
}
// 4. 封装对函数的判断
function isFunction(data) {
return getType(data) === '[object Function]'
}
// 5. 深拷贝函数封装
function cloneDeep(target) {
// 5.1 判断拷贝的是数组或者对象
let newTarget = isArray(target) ? [] : {}
// 5.2 遍历源数据
for (let key in target) {
// console.log(key);
// 如果是对象或者数组,就继续遍历
if (isArray(target[key]) || isObj(target[key])) {
// 这里使用递归函数的原因:拷贝的内层数据也可能是数组或对象,需要使用递归函数继续遍历,如果是基本类型,就直接赋值
newTarget[key] = cloneDeep(target[key])
} else if (isFunction(target[key])) {
// 如果是函数,就调用bind方法复制一个新的方法即可
newTarget[key] = target[key].bind()
} else {
// 如果是基本数据类型,就直接赋值即可
newTarget[key] = target[key]
}
}
return newTarget
}
let newObj = cloneDeep(obj)
console.log(newObj);
</script>