本人是一个web前端开发工程师,主要是vue框架,整理了一些面试题,今后也会一直更新,有好题目的同学欢迎评论区分享 ;-)
web面试题专栏:点击此处
深拷贝和浅拷贝的区别
在JavaScript中,深拷贝和浅拷贝是两种不同的对象复制方式。
浅拷贝是指将一个对象的引用复制给另一个对象,这意味着两个对象将共享相同的内存地址。当修改其中一个对象时,另一个对象也会受到影响。
深拷贝是指创建一个新的对象,并将原始对象的所有属性逐个复制到新对象中。这意味着两个对象是完全独立的,修改其中一个对象不会影响另一个对象。
浅拷贝示例
let obj1 = { name: "Alice", age: 25 };
let obj2 = obj1; // 浅拷贝
obj2.name = "Bob";
console.log(obj1.name); // 输出: Bob,因为obj1和obj2共享相同的引用
深拷贝示例
let obj1 = { name: "Alice", age: 25 };
let obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝
obj2.name = "Bob";
console.log(obj1.name); // 输出: Alice,因为obj1和obj2是完全独立的对象
在上面的深拷贝示例中,我们使用 JSON.stringify() 将原始对象转换为字符串,然后使用 JSON.parse() 将字符串转换回对象。这样做可以创建一个新的对象,并将原始对象的属性逐个复制到新对象中,从而实现深拷贝。
需要注意的是,深拷贝有时可能会有性能和内存消耗的问题,尤其是对于包含循环引用或大量嵌套对象的复杂对象。因此,在选择深拷贝或浅拷贝时,需要根据具体情况进行权衡。
特殊对象属性
- RegExp:不能拷贝
- Date:时间对象会转换成字符串
- Error:错误对象会转换成{}
- Symbol:不能拷贝
- Function:不能拷贝
测试对象如下:
var obj = {
name: "penk",
age: 30,
boo: true,
n: null,
un: undefined,
sy: Symbol("penk value"),
// big: 10n, // 浏览器没这个,nodejs可以
child: {
name: "penk son",
},
arr: [1, 2, 3, 4],
reg: /^\d+$/,
fn: function () {
console.log(this.name);
},
time: new Date(),
err: new Error("蛋疼"),
};
JSON.parse(JSON.stringify(obj));
obj对象
JSON转换对象
虽说是深拷贝,但是有些属性不行。
obj与JSON转换对象对比
手写深拷贝
封装好deepCopy
- 处理了特殊对象属性的拷贝
- 对于循环引用,进行了(WeekMap)去重处理。
// 深拷贝函数
// 避免对象中存在重复应用的优化方案
// 通过set集合的方式,obj不同才会进行操作
function deepCopy(obj, treated = new WeakMap()) {
// null 也是一个对象...
// typeof 不是object,可以直接拷贝~
// 下方数据类型可以直接返回
// Undefined|Number|String|Boolean|Null|Function|Symbol
// 1. Object跟Array 需要递归处理
// 2. Regexp Error Date 数据问题需要重新NEW
if (obj == null || typeof obj !== "object") return obj;
// 对象的类型
// console.log => '[object Object]' '[object Array]'
let string = Object.prototype.toString.call(obj);
// 对象的构造函数
let ctor = obj.constructor;
// 如果有这个obj这个键名,则直接返回键值
if (treated.has(obj)) return treated.get(obj);
let newObj = {};
// 是个复合数据类型,放的是地址
treated.set(obj, newObj);
if (string.includes("Object")) {
// for of 不能遍历普通对象,只能遍历iterator 对象
for (let i in obj) {
newObj[i] = deepCopy(obj[i], treated);
}
return newObj;
} else if (string.includes("Array")) {
// 是数组
for (let i = 0; i < obj.length; i++) {
newObj = []
newObj.push(deepCopy(obj[i], treated));
}
} else if (string.includes("RegExp")) {
// 是正则对象
newObj = new ctor(obj);
} else if (string.includes("Date")) {
// 是日期对象
newObj = new ctor(obj);
} else if (string.includes("Error")) {
// 是Error对象
newObj = new ctor(obj.message);
}
return newObj;
}
打印如下:
obj与deepCopy转换对象对比
对象是数组类型兼容性已经修改好了~
文章来源:https://www.toymoban.com/news/detail-726686.html
文章来源地址https://www.toymoban.com/news/detail-726686.html
到了这里,关于web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!