JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝)

JavaScript中的对象和数组复制可以使用浅拷贝和深拷贝的概念。在进行对象和数组复制时,使用的是复制原始值,而不是将原始值的引用作为新值传递。

浅拷贝

浅拷贝会创建一个新的对象或数组,然后将原始对象或数组的所有属性或元素复制到新的对象或数组中。新对象或数组中的属性或元素仍然指向原始对象或数组中的相同值。

创建浅拷贝有多种方法,其中最常见的方法是使用展开运算符或Object.assign()方法。

展开运算符

var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = {...original};
// 等价于
// var copy = Object.assign({}, original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["watching TV", "swimming"]}

此示例中,使用展开运算符将original对象复制到copy对象中。修改原始对象的值将不会影响副本对象中的值。但是,修改原始对象中数组的元素值会反映在副本对象中的数组中。

Object.assign()

var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = Object.assign({}, original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["watching TV", "swimming"]}

此示例中,使用Object.assign()将original对象复制到copy对象中。修改原始对象的值将不会影响副本对象中的值。但是,修改原始对象中数组的元素值会反映在副本对象中的数组中。

深拷贝

深拷贝会创建一个新的对象或数组,并将原始对象或数组中的所有属性或元素复制到新的对象或数组中。如果原始对象或数组中的属性或元素是对象或数组,则该属性或元素也将复制为新的对象或数组。

创建深层复制有多种方法,其中常见的方法是使用JSON.parse(JSON.stringify())、lodash库或递归函数。

JSON.parse(JSON.stringify())

var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = JSON.parse(JSON.stringify(original));
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

此示例中,在原始对象上调用JSON.stringify()将其序列化为JSON字符串,然后再次调用JSON.parse()将其反序列化为JavaScript对象。新的copy对象包含与original对象相同的值,但它们指向不同的内存位置。修改原始对象的值将不会影响副本对象中的值。

但是,JSON.stringify()不能序列化undefined、正则表达式、函数、Symbol和其他可以在对象中使用的特殊对象类型,例如Map和Set。

lodash库

var _ = require("lodash");
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = _.cloneDeep(original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

这个实例中,使用lodash库的_.cloneDeep()函数创建一个深层复制。lodash库可以工作在客户端和服务器端,并处理函数、Symbol等对象类型。

递归函数

function deepClone(obj) {
    if (typeof obj !== "object" || obj === null) {
        return obj;
    }
    var clone = Array.isArray(obj) ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            clone[key] = deepClone(obj[key]);
        }
    }
    return clone;
}
var original = {name: "alice", hobbies: ["reading", "swimming"]};
var copy = deepClone(original);
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

original.name = "bob";
original.hobbies[0] = "watching TV";
console.log(copy); // {name: "alice", hobbies: ["reading", "swimming"]}

这个实例中,定义了一个名为deepClone()的递归函数,它处理对象和数组并返回其副本。如果传递给它的参数不是对象或数组,则直接返回参数。如果是对象或数组,则遍历它并复制其属性或元素。递归深度克隆对象,以便包含的对象和数组也被深度克隆。

上述函数可以实现数组的深拷贝,但是,当对象属性中含有函数或正则表达式等特殊类型时,可能出现问题。

以上是关于JavaScript基础心法深浅拷贝的完整攻略。其中包含了浅拷贝与深拷贝的定义、实现方式的详细讲解以及多个示例来说明相关概念的使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝) - Python技术站

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

相关文章

  • MySQL数据库操作DQL正则表达式

    MySQL数据库操作DQL正则表达式可以帮助我们更高效地检索数据库中的数据,本文将详细讲解如何使用正则表达式进行MySQL数据库的数据检索。 什么是正则表达式 正则表达式是一种文本模式,用于匹配字符串中的一部分或整个字符串。它是在很多编程语言中都可用的工具,用于匹配、查找和替换文本。 在MySQL中,可以使用正则表达式进行模糊查询和根据一定的规则来查询数据。…

    C 2023年5月22日
    00
  • C++ 内存分配处理函数set_new_handler的使用

    当C++程序在运行时发现内存分配失败时,会抛出一个std::bad_alloc异常。为了避免程序崩溃,我们可以使用set_new_handler函数来注册一个新的处理函数,当内存分配失败时,程序会调用该函数来处理内存分配失败的情况。 set_new_handler函数的语法 set_new_handler函数是一个全局函数,它的原型如下: std::new_…

    C 2023年5月23日
    00
  • c语言处理函数调用的方法

    C语言中处理函数调用的方法是程序设计中非常基础和重要的知识。以下是处理函数调用的方法的完整攻略,包括两个示例: 函数调用方法 在C语言中,函数通常被定义在程序的顶部,并在需要的时候被调用。函数调用是通过函数名、左括号、函数参数、右括号来完成的。下面是函数调用的基本语法: function_name(arguments); 在上面的语法中,function_n…

    C 2023年5月23日
    00
  • C语言实现注册登录系统

    C语言实现注册登录系统攻略 系统功能需求 实现一个注册登录系统,包括以下功能: 用户注册 用户登录 用户修改密码 实现步骤 第一步:设计数据结构 首先需要设计一个数据结构,用于存储用户信息。为了简化实现,我们只考虑用户的用户名和密码。 typedef struct { char username[20]; char password[20]; } User;…

    C 2023年5月23日
    00
  • C语言中main函数与命令行参数详细讲解

    C语言中main函数与命令行参数详细讲解 简介 在C语言中,我们通常将所有的程序逻辑写在main函数中。main函数是C语言程序的入口函数,程序从main函数开始执行,当main函数执行完成返回时,整个程序也就结束了。 在本文中,我们将主要讲解C语言中main函数的基本语法以及如何使用命令行参数。 main函数语法 在C语言中的main函数基本语法如下: i…

    C 2023年5月23日
    00
  • Swift如何调用Objective-C的可变参数函数详解

    那么首先我们需要了解的是Objective-C中的可变参数函数的使用方式和Swift对其的调用方式。 在Objective-C中,可变参数函数通常使用va_list和va_start、va_arg、va_end等宏来进行参数的处理。其中 va_start宏接受可变参数函数的参数列表以及可变参数的最后一个非变长参数,在获取可变参数时,需要使用 va_arg宏进…

    C 2023年5月23日
    00
  • golang生成JSON以及解析JSON

    生成JSON: 在golang中生成JSON非常简单,可以使用标准库中的encoding/json包来实现。下面是一个示例代码: package main import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name…

    C 2023年5月23日
    00
  • C++操作MySQL大量数据插入效率低下的解决方法

    下面是详细讲解“C++操作MySQL大量数据插入效率低下的解决方法”的完整攻略。 问题背景 当使用C++程序操作MySQL数据库时,可能会遇到插入大量数据的情况,例如插入100万行数据。如果使用简单的插入操作,效率非常低下,而且可能会导致程序崩溃或内存溢出。因此,需要一种高效的插入方式来解决这个问题。 解决方法 一种有效的解决方法是使用MySQL的批量插入功…

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