本人是一个web前端开发工程师,主要是vue框架,整理了一些面试题,今后也会一直更新,有好题目的同学欢迎评论区分享 ;-)
web面试题专栏:点击此处
文章目录
- 深拷贝和浅拷贝的区别
- 浅拷贝示例
- 深拷贝示例
- 特殊对象属性
- obj对象
- JSON转换对象
- obj与JSON转换对象对比
- 手写深拷贝
- 封装好deepCopy
- obj与deepCopy转换对象对比
深拷贝和浅拷贝的区别
在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 也是一个对象...// 不是对象就返回,数组也是对象~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[i] = 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);} else if (string.includes("Symbol")) {// 是Symbol对象newObj = new ctor(obj.description);} else if (string.includes("Function")) {// 是方法newObj = function (...arg) {target.call(this, ...arg);};}return newObj;
}
打印如下: