还记得之前面试时,某公司第一道题就是这个,就是手写一个深拷贝,并且表示这个是很基础的题如果写不出来就无法进行接下来的流程,所以这一题直接导致我凉凉了!终于有时间整理一下啦,希望对大家有所帮助。
1.可以递归实现json.parse(json.stringfy())功能
function deepClone(obj) {
if (obj === null || typeof obj !== "object") {
// 如果是null或者不是对象类型,直接返回
return obj;
}
if (obj instanceof Date) {
// 如果是日期类型,返回新的日期对象
return new Date(obj);
}
if (obj instanceof RegExp) {
// 如果是正则表达式类型,返回新的正则表达式对象
return new RegExp(obj);
}
// 如果是数组类型,返回新的数组对象
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item));
}
// 如果是对象类型,返回新的对象
const newObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
// 测试
const obj = {
a: 1,
b: [1, 2, 3],
c: {
d: "deepClone"
},
e: new Date(),
f: /deepClone/,
};
const newObj = deepClone(obj);
console.log(newObj); // { a: 1, b: [ 1, 2, 3 ], c: { d: 'deepClone' }, e: 2021-07-28T06:58:10.072Z, f: /deepClone/ }
需要注意以下几点:
1.要考虑到各种数据类型的情况,如对象、数组、日期、正则等;
2.数组和对象中的每个元素都要递归调用 deepClone 方法;
3.对象的属性需要判断是否是自身属性,避免遍历到原型链上的属性。
2.还有一种比较奇特的写法,就是使用 eval 函数来实现
function jsonParse(string) {
return eval(`(${string})`);
}
function jsonStringify(obj) {
return JSON.stringify(obj);
}
// 测试
const obj = {
a: 1,
b: [1, 2, 3],
c: {
d: "jsonParse"
},
e: new Date(),
f: /jsonParse/,
};
const json = jsonStringify(obj);
console.log(json); // {"a":1,"b":[1,2,3],"c":{"d":"jsonParse"},"e":"2021-07-28T07:07:14.466Z","f":{}}
const newObj = jsonParse(json);
console.log(newObj); // { a: 1, b: [ 1, 2, 3 ], c: { d: 'jsonParse' }, e: 2021-07-28T07:07:14.466Z, f: {} }
需要注意以下几点:
1.在 jsonParse 中,需要将传入的字符串用 () 包裹起来,以便将其解析为一个对象;
2.虽然这种写法比较简洁,但是存在安全风险,不建议在实际开发中使用。
好啦!大致整理出这两种,不过第二种方式不推荐哦!希望可以帮助到大家。下期见啦