web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理

这篇具有很好参考价值的文章主要介绍了web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理,前端面试题,JS深拷贝,web前端面试题

JSON转换对象

虽说是深拷贝,但是有些属性不行。

web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理,前端面试题,JS深拷贝,web前端面试题

obj与JSON转换对象对比

web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理,前端面试题,JS深拷贝,web前端面试题

手写深拷贝

封装好deepCopy

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

打印如下:

web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理,前端面试题,JS深拷贝,web前端面试题

obj与deepCopy转换对象对比

对象是数组类型兼容性已经修改好了~

web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理,前端面试题,JS深拷贝,web前端面试题文章来源地址https://www.toymoban.com/news/detail-726686.html

到了这里,关于web前端面试-- js深拷贝的一些bug,特殊对象属性(RegExp,Date,Error,Symbol,Function)处理,循环引用weekmap处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 持续不断更新中... 自己整理的一些前端知识点以及前端面试题,包括vue2,vue3,js,ts,css,微信小程序等

    答: 在普通的前端项目工程中,在script标签中增加setup即可使用api 使用setup()钩子函数 答: 不要在计算属性中进行异步请求或者更改DOM 不要直接修改computed的值 区别: 计算属性值基于其响应式依赖被缓存,意思就是只要他之前的依赖不发生变化,那么调用他只会返回之前缓

    2024年02月11日
    浏览(39)
  • C++类和对象终章——友元函数 | 友元类 | 内部类 | 匿名对象 | 关于拷贝对象时一些编译器优化

    🌸作者简介: 花想云 ,在读本科生一枚,致力于 C/C++、Linux 学习。 🌸 本文收录于 C++系列 ,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新! 🌸 相关专栏推荐: C语言初阶系列 、 C语言进阶系列 、 数据结构与算法 、 Linu

    2023年04月15日
    浏览(29)
  • JavaScript之深度克隆、多种实现方式、列举各种方式的优缺点、对象自有属性、拷贝、复制

    在 JavaScript 中,对象和数组是引用类型,当将一个对象或数组赋值给另一个变量时,它们实际上是共享同一块内存空间。这意味着对一个对象或数组的修改会影响到所有引用它的变量。 为了创建一个独立的副本,可以使用深克隆。 JSON.stringify() 方法将 JavaScript 对象转换为一个

    2024年02月02日
    浏览(32)
  • 6.函数是特殊的对象2 - JS

    在第一部分中,主要总结了函数作为一个对象的常见属性( name/length )、如何自定义属性以及如何使用函数构造器( Function )。 这里总结函数作为对象的常见方法( apply/call/bind/toString )。 call 方法指定 this 并且逐个提供参数。 基本语法 thisArg ,调用 f 时指定的 this 值:

    2024年02月19日
    浏览(23)
  • 前端面试题---深拷贝、浅拷贝的实现和解构赋值

    在 JavaScript 中实现深拷贝和浅拷贝可以采用不同的方法。下面分别介绍这两种拷贝方式的实现方式 1.浅拷贝(Shallow Copy) 浅拷贝(shallow copy)是一种复制对象或数组的操作,创建一个新的对象或数组,并将原始对象或数组的属性或元素的引用复制到新的对象或数组中。这意味

    2024年02月08日
    浏览(73)
  • JS中实现数组和对象深拷贝的4种方法

    一、数组深拷贝的4种方法 1. 使用JSON.parse()和JSON.stringify(): const arr1 = [1, 2, 3, 4]; const arr2 = JSON.parse(JSON.stringify(arr1)); 2. 使用Array.from(): const arr1 = [1, 2, 3, 4]; const arr2 = Array.from(arr1); 3. 使用扩展运算符: const arr1 = [1, 2, 3, 4]; const arr2 = [...arr1]; 4. 使用Array.map(): const arr1 = [1, 2, 3

    2024年02月14日
    浏览(25)
  • 【JS】js给对象动态添加、设置、删除属性名和属性值

    js中访问对象属性一共有两种方法:点获取法和方括号获取法。 使用点符号访问属性值 alert( user.name ); // John 使用方括号访问属性值 alert( user[name]); // John 注意: 如果我们遍历一个对象,我们获取属性的顺序是和属性添加时的顺序相同吗? 简短的回答是:“有特别的顺序”:整

    2023年04月13日
    浏览(37)
  • js向对象添加属性

    1、使用 对象.属性名 添加 2、使用 对象[属性名]添加 3、使用 prototype添加

    2024年02月09日
    浏览(32)
  • 【面试题】:前端怎么实现权限设计及遇到的bug

    一.权限的概念         前端权限分为页面权限、按钮权限、API权限。 二.页面权限的实现过程         ①用户登录进去调用获取用户信息接口,后端会给我们返回一个权限标识符         ②在获取到数据之后,我们就要判断用户能访问到哪些页面,我们可以在vuex中

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包