【JavaScript】面试手撕深拷贝

这篇具有很好参考价值的文章主要介绍了【JavaScript】面试手撕深拷贝。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言
【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

🌈个人主页: 鑫宝Code
🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础
💫个人格言: "如无必要,勿增实体"

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言


【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

引入

上次讲了浅拷贝,这次我们来讲深拷贝。有一说一,深拷贝也算是面试时非常常见的题目了。🐶

深拷贝的作用

首先为什么需要深拷贝,因为浅拷贝无法满足我们对原始数据完整、独立复制的需求。我们希望修改新对象不会影响原对象。

深浅拷贝的区别

这里引用ConardLi大佬的理解

浅拷贝

创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。

  • 如果属性是基本类型,拷贝的就是基本类型的值.
  • 如果属性是引用类型,拷贝的就是内存地址

所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言
深拷贝

将一个对象从内存中完整的拷贝一份出来

  • 从堆内存中开辟一个新的区域存放新对象
  • 且修改新对象不会影响原对象
【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

深拷贝实现方式

JSON.parse(JSON.stringify())

遥记当年,我当时还是大三的时候,背了一周的面经就跑去字节面试实习生了。面试官就让我手撕深拷贝。

我当时才20刚出头,前端面经也才抱起来背了不到一周。这种题目我写的来得?

跟面试官面面相觑了半天,突然灵机一动,JSON.parse(JSON.stringfy())大法一定可以。

我当时非常开心的说出了这个答案, 面试官当时好像有点尬住了,嘴角流露出一股察摸不到的笑容。

但可能由于接受过专业的训练,也只在那短短的时间内便消失不见。🐶

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

介绍

JSON.parse(JSON.stringify()),首先使用利用JSON.stringify将对象转成JSON字符串。 再用JSON.parse把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

使用例子
const a = {
    name: '张三',
    score:{
        math: 100
    }
}

const b = JSON.parse(JSON.stringify(a));

// 改变b中的对象的值
b.score.math = 60;

console.log('a的值',a);
console.log('b的值',b);

/**
 * 输出的结果如下
 * a的值 { name: '张三', score: { math: 100 } }
 * b的值 { name: '张三', score: { math: 60 } }
 */
缺点

记个TODO:下次写文章详细分析下JSON.stringify的缺点。

  • 不会拷贝对象上为undefined的值
  • 不能处理函数
  • 不能处理正则
  • 循环引用会报错
  • Symol会丢失等

Lodash的cloneDeep

续借上文,面试官笑了笑,说JSON.parse(JSON.stringify())这个方式有如上几个缺点,你能不能换个更好的方式将这个问题解决呢?

这又一次的让我陷入了思索,又开始了与面试官的面面相觑😅。突然我想起了以前用的Lodash,其中有一个NB的方法。cloneDeep,当时我洋洋得意,心想lodash库的方法,总不可能还有缺点吧?

此时,面试官的表情稍稍有点微妙,我的第六感告诉我,我好像答错了,不过我认为我回答的没问题呀。

晌久,面试官叹了口气说,我是让你手撕,手撕懂吗?

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

介绍

_.cloneDeeplodash库提供的深拷贝的方法,非常实用,建议背诵😂。

使用例子
import * as _ from "lodash";

const a = {
  name: "张三",
  score: {
    math: 100,
  },
};

const b = _.cloneDeep(a);
缺点

暂无,🐮的lodash库,🐮的cloneDeep函数。

手撕深拷贝

诶,还是得手撕呀,来吧来吧,还是得给面试官露一手的😜

基础版本

多年面试经验告诉我,一般写出这个版本,几乎都让过了,顶多在回答一下循环引用问题如何解决。一般不太会让写一个比较完美的深拷贝的。🐶

  1. 首先,我们要拷贝的数据类型有两种,分别是ArrayObject
  2. 如果对象里的属性还是对象,那么采用递归对这个对象再进行拷贝
  3. 如果对象里的属性不是对象,那么直接返回即可。

代码如下:

function deepClone(target) {
  if (typeof target === "object") {
    let cloneTarget = Array.isArray(target) ? [] : {};
    for (const key in target) {
      cloneTarget[key] = deepClone(target[key]);
    }
    return cloneTarget;
  } else {
    return target;
  }
}

const a = {
  name: "张三",
  score: {
    math: 100,
  },
};

const b = deepClone(a);
/** 输出的b与a一样 **/

但是这样实现会有若干个问题:

  1. 循环引用问题无法解决
  2. DateRegExp等对象无法拷贝

进阶版本

之所以用weakMap,是因为weakMap的键是弱引用,可以在任何时刻被回收。

如果想了解更清楚进阶深拷贝的原理,可以参阅 如何写出一个惊艳面试官的深拷贝?

function deepClone(target, hash = new WeakMap()) {
  if (target === null) return null;
  if (typeof target !== "object") return target;
  if (target instanceof Date) return new Date(target);
  if (target instanceof RegExp) return new RegExp(target);
  // 如果hash里有值,立马返回
  if (hash.has(target)) return hash.get(target);

  const cloneTarget = Array.isArray(target) ? [] : {};

  hash.set(target,cloneTarget);

  if (typeof target === "object") {
    for (const key in target) {
      cloneTarget[key] = deepClone(target[key],hash);
    }
    return cloneTarget;
  } else {
    return target;
  }
}

const a = {
  name: "张三",
  score: {
    math: 100,
  },
  date: new Date(),
  regex: /^\d{3,4}-\d{5,8}$/,
};

a.child = a;

const b = deepClone(a);

运行结果如下:

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

参考资料

如何写出一个惊艳面试官的深拷贝?

浅拷贝与深拷贝

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言

【JavaScript】面试手撕深拷贝,JavaScript,javascript,面试,开发语言文章来源地址https://www.toymoban.com/news/detail-839278.html

到了这里,关于【JavaScript】面试手撕深拷贝的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【JavaScript】手撕前端面试题:手写Object.create | 手写Function.call | 手写Function.bind

    🖥️ NodeJS专栏:Node.js从入门到精通 🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述) 🖥️ TypeScript知识总结:TypeScript从入门到精通(十万字超详细知识点总结) 🧑‍💼个人简介:大三学生,一个不甘平庸的平凡人🍬 👉

    2024年02月21日
    浏览(44)
  • 手撕前端面试题【javascript~ 总成绩排名、子字符串频次统计、继承、判断斐波那契数组等】

    html页面的骨架,相当于人的骨头,只有骨头是不是看着有点瘆人,只有HTML也是如此。 css,相当于把骨架修饰起来,相当于人的皮肉。 js(javascripts),动起来,相当于人的血液,大脑等一切能使人动起来的器官或者其他的。 在刷题之前先介绍一下牛客。Leetcode有的刷题牛客都有,

    2024年01月15日
    浏览(34)
  • JavaScript深拷贝(js深拷贝,JavaScript递归函数,实现深拷贝)

    简述:JavaScript的深拷贝和浅拷贝大家都比较熟悉,今天来分享下深拷贝,就是使用该函数时,会复制拷贝一份该数据,修改该数据属性,不会改变原有数据,就是把复制的对象所引用的对象全都复制了一遍,具体实现如下; 1、定义拷贝对象; 2、定义递归函数deepClone(),实现

    2024年02月15日
    浏览(48)
  • 开发语言漫谈-JavaScript

           JavaScript、Java名字很相近,但它们没有任何亲缘关系,是由不同公司开发的编程语言。Java由Sun公司(后被Oracle收购)开发,JavaScript最初是由Netscape公司开发的(当年浏览器的霸主)。JavaScript最初的名字是 LiveScript,Netscape将其命名为 JavaScript,无非是蹭 Java流量。当

    2024年04月16日
    浏览(37)
  • JavaScript深浅拷贝

    1. js浅拷贝只是创建了一个新的对象,复制了原有对象的基本类型的值。 手写实现  2. 深拷贝的原理和实现 将一个对象从内存中完整地拷贝出来一份给目标对象,并从堆内存中开辟一个全新的空间存放新的对象,且新对象的修改并不会改变原对象,二者实现真正的分离

    2024年01月18日
    浏览(32)
  • JavaScript深浅拷贝的几种方式

    深浅拷贝主要是针对于引用类型而言的 1. JSON.parse(JSON.strigify(Str)) JSON.stringify() 该方法用于将一个字转换为JSON字符串,该字符串符合JSON格式,并且可以被JSON.parse()方法还原。 对于原始类型的字符串,转换结果会带双引号 如果要转换的对象的属性是undefined,函数或xml对象,该

    2024年01月19日
    浏览(33)
  • 深入探索前端之道:JavaScript深拷贝与浅拷贝的解析与实现

    前端开发中,数据的复制是一个常见的操作。尤其是在处理对象和数组时,我们需要考虑的是一个浅拷贝还是深拷贝。那么,什么是深拷贝和浅拷贝?它们在前端开发中有什么作用?如何实现这两种拷贝?这是我们在本文将讨论的问题。 浅拷贝 浅拷贝是一种数据复制方式,

    2024年02月10日
    浏览(26)
  • 建站系列(五)--- 前端开发语言之HTML、CSS、JavaScript

    建站系列(一)— 网站基本常识 建站系列(二)— 域名、IP地址、URL、端口详解 建站系列(三)— 网络协议 建站系列(四)— Web服务器之Apache、Nginx 建站系列(五)— 前端开发语言之HTML、CSS、JavaScript 建站系列(六)— 后端开发语言 建站系列(七)— 常用前后端框架

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

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

    2024年02月02日
    浏览(32)
  • (自己动手开发自己的语言练手级应用)JSON(JavaScript Object Notation) 产生式(BNF)

     写自己的开发语言时,很多人都会拿JSON当第一个练习对象 开源net json FJSON 解析工具 https://dbrwe.blog.csdn.net/article/details/107611540?spm=1001.2014.3001.5502 以上是JSON的简化产生式表示形式。其中, json 是最顶层的规则,可以是一个对象或一个数组。 object 表示一个对象,由一对大括号

    2024年02月10日
    浏览(36)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包