javascript进阶篇深拷贝实现的四种方式

Javascript进阶篇:深拷贝实现的四种方式

在Javascript中,数据类型可以分为原始类型和引用类型。其中,原始类型在赋值、作为函数参数、返回值传递等情况下,直接进行值的传递。而引用类型则是传递引用地址。这样一来,在同一个作用域下、赋值、作为函数参数、返回值传递等情况下,多个变量可能会指向同一引用地址的内存空间,导致某些问题。为了避免这种问题,我们需要对引用类型进行深拷贝。

本文将介绍四种Javascript实现深拷贝的方式:

方式一:JSON.parse(JSON.stringify(obj))

利用JSON.stringify可以把JSON对象转换为字符串,JSON.parse方法可以把字符串转换为对象的特性,可以达到深拷贝的效果。

let obj = {a: 1, b: {c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj === newObj); // false
console.log(obj.b === newObj.b); // false

但也有需要注意的点,比如:

  • undefined无法被序列化,所以在原对象中该属性会被忽略;
  • NaN、Infinity和-Infinity会被转化为null;
  • Date日期对象也无法被序列化(Javascript中日期对象都有一个toString方法,因此JSON.stringify调用Date对象时会把日期转换成字符串);
  • 对象中函数属性会被忽略掉;
  • 对象中RegExp、Error对象等特殊对象无法被序列化;
  • 如果obj对象中存在循环引用的情况也无法正确实现深拷贝。

方式二:递归遍历对象拷贝

递归遍历对象,对于每一个属性进行递归操作,从而实现深拷贝。

function deepClone(obj) {
  let newObj = obj instanceof Array ? [] : {};
  for(let i in obj){
    if (typeof obj[i] === 'object') {
      newObj[i] = deepClone(obj[i]);
    } else {
      newObj[i] = obj[i];
    }
  }
  return newObj;
}

let obj = {a: 1, b: {c: 2}};
let newObj = deepClone(obj);
console.log(obj === newObj); // false
console.log(obj.b === newObj.b); // false

需要注意的是,递归深拷贝也需要注意循环引用的问题。

方式三:利用Object.assign

Object.assign方法可以使用多个源对象中的属性和方法拷贝到一个目标对象中去。利用这个特性,我们也可以实现深拷贝。

function deepClone(obj) {
  let newObj = obj instanceof Array ? [] : {};
  if (typeof obj !== 'object') {
    return obj;
  }
  for(let i in obj){
    if (typeof obj[i] === 'object') {
      newObj[i] = deepClone(obj[i]);
    } else {
      newObj[i] = obj[i];
    }
  }
  let temp = Object.assign({}, obj, newObj);
  return temp;
}

let obj = {a: 1, b: {c: 2}};
let newObj = deepClone(obj);
console.log(obj === newObj); // false
console.log(obj.b === newObj.b); // false

与上一个方法类似,也需要注意循环引用的问题。

方式四:使用第三方库

使用第三方库中的深拷贝方法,如lodash中的_.cloneDeep方法。这个方法可以深度克隆一个对象,包括原型链。

let obj = {a: 1, b: {c: 2}};
let newObj = _.cloneDeep(obj);
console.log(obj === newObj); // false
console.log(obj.b === newObj.b); // false

需要注意的是,使用第三方库虽然方便,但是也会增加代码依赖和体积。

总结

以上四种Javascript实现深拷贝的方式,各有利弊。在具体项目中,我们需要根据实际情况进行选择。需要注意的是,在实现深拷贝时,需要考虑到循环引用、特殊对象等特殊情况,以避免影响程序的正常运行。

两条示例:

  • 示例一:使用JSON.parse(JSON.stringify(obj))进行深拷贝
let obj = {a: 1, b: {c: 2}};
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj === newObj); // false
console.log(obj.b === newObj.b); // false
  • 示例二:使用第三方库lodash的深拷贝方式
let obj = {a: 1, b: {c: 2}};
let newObj = _.cloneDeep(obj);
console.log(obj === newObj); // false
console.log(obj.b === newObj.b); // false

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript进阶篇深拷贝实现的四种方式 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • 如何使用jQuery Simone Plugin设计窗口管理器

    使用jQuery Simone Plugin(下文简称Simone)可以方便地实现一个窗口管理器,使得网站在交互和界面设计方面更加优秀。下面是使用Simone设计窗口管理器的完整攻略。 1. 导入Simone Simone可以在官方网站上下载,并可以通过<script>标签引入。在<head>标签中添加以下代码: <script…

    jquery 2023年5月12日
    00
  • 如何用jQuery在页面的所有段落上显示一个dblclick事件的信息

    要在页面的所有段落上显示一个dblclick事件的信息,我们可以使用以下步骤: 使用$(“p”)选择器选择所有段落元素。 使用.on()函数将dblclick事件绑定到每个段落元素上,例如$(“p”).ondblclick”, function() {})。 在事件处理程序函数中,使用$(this)获取当前段落元素,并使用.text()函数获取其文本内容。 …

    jquery 2023年5月9日
    00
  • JQuery入门——用one()方法绑定事件处理函数(仅触发一次)

    下面就是一个完整的“JQuery入门——用one()方法绑定事件处理函数(仅触发一次)”攻略。 1. 概述 在jQuery中,我们可以使用on()方法或bind()方法来绑定事件处理函数,以响应用户的操作。但是,如果我们需要一个事件处理函数仅执行一次,怎么办呢?这个时候,就需要使用one()方法了。one()方法与on()方法类似,但只会触发一次事件处理函数…

    jquery 2023年5月28日
    00
  • jQuery初识之设计思想方法函数示例

    关于“jQuery初识之设计思想方法函数示例”的完整攻略,以下是我整理的内容: 设计思想 jQuery的设计思想可以用两句话来概括: Write less, do more(写得少,做得多) Don’t reinvent the wheel(不要重复发明轮子) 首先,jQuery让我们能够用更少的代码完成更多的功能。比如,在纯JavaScript中获取某个元…

    jquery 2023年5月27日
    00
  • jquery提升性能最佳实践小结

    jQuery提升性能最佳实践小结 jQuery是一个流行的JavaScript库,由于它的灵活性和易用性,它成为了很多开发者的首选。然而,如果不正确地使用它,会对网站的性能带来不良影响。下面将介绍一些jQuery提升性能的最佳实践。 1. 使用ID选择器而不是类选择器 相比于类选择器,ID选择器的性能要更好。因为ID唯一,浏览器可以直接使用getElemen…

    jquery 2023年5月28日
    00
  • 超详细讲解Java秒杀项目登陆模块的实现

    超详细讲解Java秒杀项目登陆模块的实现 在Java秒杀项目中,登陆模块是非常重要的一部分。本文将详细讲解如何实现Java秒杀项目的登陆模块。 确定登陆方式 在实现登陆模块之前,我们需要确定登陆方式。Java秒杀项目通常有三种登陆方式: 普通用户账号密码登陆 手机号短信验证登陆 第三方账号登陆 本文以普通用户账号密码登陆为例介绍登陆模块的实现。 实现登陆接口…

    jquery 2023年5月27日
    00
  • 浅谈jquery之on()绑定事件和off()解除绑定事件

    浅谈jquery之on()绑定事件和off()解除绑定事件 什么是on()和off()方法 在jQuery中,on()和off()是绑定和解除绑定事件的方法。它们是jQuery事件处理的基础方法,使得我们能够对元素进行事件监听和处理。 on()方法 $(selector).on(event, childSelector, data, function); 语…

    jquery 2023年5月28日
    00
  • 纯JS实现可用于页码更换的飞页特效示例

    如果你想实现网页中的翻页效果,通常会使用翻页插件或者直接使用服务端渲染来完成。但是,如果你希望通过纯JS来实现页码的更换和动画效果,可以使用飞页特效。在本篇攻略中,我们将详细讲解如何实现这种效果。 什么是飞页特效 飞页特效是一种网页页面切换效果,可以实现类似于翻页效果的动画。这种效果最常用于实现分页中的切换效果,但是也可以用于一些其他类型的页面过渡或切换。 …

    jquery 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部