JS浅拷贝和深拷贝原理与实现方法分析

JS浅拷贝和深拷贝原理与实现方法分析

一、浅拷贝

浅拷贝是将一个对象的属性值复制到另一个对象,新对象和旧对象的各个属性指向的是同一个对象。这意味着修改其中一个对象的属性会同时修改另一个对象的属性。

1. 实现方法

1.1 Object.assign()

ES6引入了Object.assign()方法,该方法可以用来浅拷贝对象。

let obj1 = { name: '张三', age: 18 };
let obj2 = Object.assign({}, obj1);
console.log(obj2); // { name: '张三', age: 18 }

1.2 手写浅拷贝

也可以手动编写一个浅拷贝的方法,该方法使用循环遍历原对象的属性并将其复制到新对象上。

function shallowClone(obj) {
  let newObj = {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
}

let obj1 = { name: '张三', age: 18};
let obj2 = shallowClone(obj1);
console.log(obj2); // { name: '张三', age: 18 }

2. 示例说明

2.1 使用Object.assign()实现浅拷贝

let obj1 = { name: '张三', age: 18 };
let obj2 = Object.assign({}, obj1);
obj1.age = 20;
console.log(obj2.age); // 输出 18

这里通过Object.assign()方法将obj1对象浅拷贝到obj2对象上。当修改obj1的属性age为20时,obj2对象的属性age并未改变,由此可以证明这是一个浅拷贝。

2.2 手写浅拷贝实现

function shallowClone(obj) {
  let newObj = {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
}

let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = shallowClone(obj1);
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山', '看电影']

这里使用手写的浅拷贝方法,将obj1对象浅拷贝到obj2对象上。当修改obj1的属性hobby,将新元素'看电影'加入hobby属性时,obj2的hobby属性同样改变了,由此可以证明这是一个浅拷贝。

二、深拷贝

深拷贝是将一个对象的属性值复制到另一个对象,新对象指向的是完全独立的新对象,对新对象的修改不会影响原对象。

1. 实现方法

1.1 JSON.parse()和JSON.stringify()

可以通过JSON.stringify()将对象转换为字符串,然后再通过JSON.parse()将字符串转换回对象,从而实现深拷贝。这种方法的局限是,如果对象中存在函数、正则表达式等特殊类型,将无法正确处理。

let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']

1.2 手写递归深拷贝

手写递归深拷贝方法,可以确保所有类型的属性都能被正确地拷贝。

function deepClone(obj) {
  if (obj === null) return null;
  if (typeof obj !== "object") return obj;
  if (obj instanceof RegExp) return new RegExp(obj);
  if (obj instanceof Date) return new Date(obj);
  let newObj = new obj.constructor();
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}

let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = deepClone(obj1);
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']

2. 示例说明

2.1 使用JSON.parse()和JSON.stringify()实现深拷贝

let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']

这里使用了JSON.parse()和JSON.stringify()方法,将obj1对象深拷贝到obj2对象上。当修改obj1的属性hobby,将新元素'看电影'加入hobby属性时,obj2的hobby属性并没有改变,由此可以证明这是一个深拷贝。

2.2 手写递归深拷贝实现

function deepClone(obj) {
  if (obj === null) return null;
  if (typeof obj !== "object") return obj;
  if (obj instanceof RegExp) return new RegExp(obj);
  if (obj instanceof Date) return new Date(obj);
  let newObj = new obj.constructor();
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}

let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = deepClone(obj1);
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']

这里使用手写的递归深拷贝方法,将obj1对象深拷贝到obj2对象上。当修改obj1的属性hobby,将新元素'看电影'加入hobby属性时,obj2的hobby属性并没有改变,由此可以证明这是一个深拷贝。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS浅拷贝和深拷贝原理与实现方法分析 - Python技术站

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

相关文章

  • 简单实现jQuery上传图片显示预览功能

    实现jQuery上传图片显示预览功能的过程可以分为以下步骤: 步骤1:HTML结构准备 首先,在HTML中需要创建一个input元素,用于选择图片文件,以及一个img元素,用于显示图片预览效果。这里我们给它们分别添加了id为”fileInput”和”idForImg”,如下所示: <input type="file" id=&quo…

    jquery 2023年5月27日
    00
  • jQWidgets jqxMenu restore() 方法

    以下是关于 jQWidgets jqxMenu 组件中 restore() 方法的详细攻略。 jQWidgets jqxMenu restore() 方法 jQWidgets jqxMenu 组件的 restore() 方法用于还原菜单到初始状态。该方法通过编程方式调用。 语法 $(‘#menu’).jqxMenu(‘restore’); // 还原菜单到初…

    jquery 2023年5月12日
    00
  • jQWidgets jqxTabs enableScrollAnimation属性

    jQWidgets Library是一款强大的UI组件库,其中的jqxTabs是一个非常实用的选项卡控件。enableScrollAnimation属性是jqxTabs组件中关于卷轴滚动的一个重要属性,在使用jqxTabs进行页面布局时非常有用。 enableScrollAnimation属性是什么? enableScrollAnimation属性是jqxT…

    jquery 2023年5月12日
    00
  • jQWidgets jqxGrid toolbarheight属性

    jQWidgets jqxGrid toolbarheight属性 jQWidgets jqxGrid 是一种表格控件,用于在 Web 应用程序中创建表格。toolbarheight 属性是 jqxGrid 控件的一个属性,用于工具栏的高度。本文将详细讲解 toolbarheight 属性的使用方法,并提供两个示例说明。 属性 toolbarheight 属…

    jquery 2023年5月10日
    00
  • jquery加载页面的方法(页面加载完成就执行)

    下面是详细的”jquery加载页面的方法(页面加载完成就执行)”攻略: 1. 什么是”页面加载完成”? 在介绍”jquery加载页面的方法(页面加载完成就执行)”之前,需要先了解下什么是”页面加载完成”。当页面所有资源(包括样式、图片、脚本等)都加载完成后,才能算是页面加载完成。通常我们使用 window.onload 或 jQuery的 $(documen…

    jquery 2023年5月27日
    00
  • jquery实现图片预加载

    当我们在网页中使用大量图片时,为避免用户在图片加载时出现空白的情况,我们可以采用图片预加载的技术。本文将详细讲解如何使用jQuery实现图片预加载。 步骤一:创建预加载列表 首先,我们需要创建一个列表,该列表将包含我们要预加载的所有图片。为了简化示例,我们在这里只预加载两张图片。 <ul id="imgList" style=&qu…

    jquery 2023年5月27日
    00
  • JQuery datepicker 使用方法

    JQuery datepicker 是一个十分常用的日期选择器插件,可以帮助我们快速开发出属于自己的日期选择器功能。下面是根据官方文档和个人实践总结的使用方法攻略: 一、引入JQuery 和 datepicker插件文件 <head> <link rel="stylesheet" href="//code.jq…

    jquery 2023年5月28日
    00
  • jQuery Deferred和Promise创建响应式应用程序详细介绍

    jQuery Deferred和Promise创建响应式应用程序详细介绍 什么是jQuery Deferred和Promise jQuery Deferred提供了一种方便的方法来跟踪异步函数的状态,Deferred有三种状态:pending、resolved、rejected。Promise则是Deferred的一个快照,只有查看的权限,不能把Promis…

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