JavaScript-深拷贝、浅拷贝

作者: 苏茶茉芳_亚泽伊 | 来源:发表于2019-07-26 11:03 被阅读10次

本文档适用于有一定经验的开发者。我们默认你已经掌握了指针的概念(也可称为地址) ,如果你是新手,你可能需要先了解 指针的概念

我们在JS中经常需要复制一个对象或数组。
当我们直接使用=赋值时,我们实际只赋值了这个对象的指针。这种情况 连拷贝都算不上
例:如下我们给array2赋值,实际是赋值给array2一个指针,指针指向array1指向的数组。因此我们编辑 array2 时,array1也会变。

let array1 = [1,2,3]
let array2 = array1
array2[0] = 100
/*
 array1
>(3) [100, 2, 3]
array2
(3) [100, 2, 3]
*/

浅拷贝可以将数组(对象)的第一层拷贝下来。
ES6给我们提供了两个方便的浅拷贝方法:
Array.from()Object.assign()
例:下面我们通过Array.from()对array3进行浅拷贝。我们可以看出,当我们修改array4的普通元素时,array3已经不会随着改变了。但是浅拷贝只是拷贝了第一层的元素,如果第一层元素含有对象(数组),我们只拷贝一个指针(地址)。array4通过这个指针(地址)访问的对象将是与array3是相同的。

let array3 = [1,2,3,{a:1,b:2,c:3}]
let array4 = Array.from(array3)
array4[0] = 100
array4[3].a = 100
/*
array3
>(4) [1, 2, 3, {a: 100, b: 2, c: 3}]
array4
>(4) [100, 2, 3, {a: 100, b: 2, c: 3}]
*/

目前JS常见的深拷贝有两种方式。第一种种是两次JSON化:
let array6 = JSON.parse(JSON.stringfiy(array5))
这种方法很简单,但是当元素含有undefined正则表达式时函数会抛出异常。
第二种深拷贝是逐层遍历逐一赋值的方法,要麻烦一些,但是没有第一种的缺点。
目前,这两种以外的拷贝方式都是浅拷贝。例如for...of遍历中的item实际是对对象元素的浅拷贝。

// 例:逐层遍历逐一赋值的深拷贝工具类
class deepCopy {
    static toRawType(value) {
        return Object.prototype.toString.call(value).slice(8, -1);
    }
    /* 已整合在tools中 */
    static copy(obj) {
        let emptyObject = null;
        if (this.toRawType(obj) == 'Object') {
            emptyObject = {};
        }
        else if (this.toRawType(obj) == 'Array') {
            emptyObject = [];
        }
        else {
            return obj;
        }
        for (let key in obj) {
            if (typeof obj[key] != 'object' || obj[key] == null) {
                emptyObject[key] = obj[key];
            }
            else {
                emptyObject[key] = this.copy(obj[key]);
            }
        }
        return emptyObject;
    }
}
let array5 = [1,2,3,{a:1,b:2,c:3}]
let array6  = deepCopy.copy(array5)
array6[3].a = 100
/*
array3
>(4) [1, 2, 3, {a: 1, b: 2, c: 3}]
array4
>(4) [1, 2, 3, {a: 100, b: 2, c: 3}]
*/

相关文章

  • JavaScript-深拷贝、浅拷贝

    本文档适用于有一定经验的开发者。我们默认你已经掌握了指针的概念(也可称为地址) ,如果你是新手,你可能需要先了解 ...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • JavaScript-浅拷贝vs深拷贝

    原文地址博客积累地址 概念 深拷贝和浅拷贝都是针对的引用类型 浅拷贝:拷贝的是地址,最终两个变量指向同一份数据,修...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • 2018-10-10day9函数基础

    1.浅拷贝、深拷贝 copy.copy(对象):浅拷贝copy.deepcopy(对象):深拷贝""" """拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

网友评论

    本文标题:JavaScript-深拷贝、浅拷贝

    本文链接:https://www.haomeiwen.com/subject/elyohctx.html