本人是一个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

  1. 处理了特殊对象属性的拷贝
  2. 对于循环引用,进行了(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;}

打印如下:

obj与deepCopy转换对象对比