zoukankan      html  css  js  c++  java
  • 深拷贝与浅拷贝

    对于基本类型的数据,深拷贝与浅拷贝都相同,都是开辟一块新的空间,将数组赋值存入。旧值的改变不会影响新值,然鹅对于引用类型的数据就不相同了。

    浅拷贝

    对于引用类型的数据实行浅拷贝,当旧值发生改变时,新值也会改变,这是因为浅拷贝仅仅只是在栈中新开辟一块空间,将旧值存在栈中的指针复制给新值,新旧值指向的是同一块内存。旧值改变时,新值自然也是改变了的。

    var a = [1];
    var b = a;
    a[0] = 2;
    console.log(b); // [2]

    实现浅拷贝的方式

    Object.assign

    展开运算符

    只能实现简单数据类型的深拷贝

    var a = {name:'ashen'}
    var b = {...a}

    深拷贝

    而在新拷贝中,对于引用类型的拷贝是在堆中新开辟一块空间,将旧的数值复制该这个空间,再在栈中开辟一块空间指向堆中这个地址。新旧值已不再相互影响.

    实现深拷贝的几种方式

    使用JSON方式

    var a = [1, 2, 3];
    var b = JSON.parse(JSON.stringify(a));
    a[1] = 1;
    console.log(b); // [1, 2, 3]

    缺点:

    1. 不能实现其中函数的拷贝
    2. 无法拷贝原型链上的属性和方法
    3. 数据层次很深时,会栈溢出

    使用递归

    function deepClone(obj) {
            var newObj = Array.isArray(obj) ? [] : {};
            for (var key in obj) {
                if (obj[key] instanceof Object) {
                    newObj[key] = deepClone(obj[key])
                }else{
                    newObj[key] = obj[key]
                }
            }
            return newObj;
        }
    
        var a = [{name:'ashen', age: 21}, 1]
        var b = deepClone(a);
        console.log(b)

    使用数组的forEach实现

    function deepClone(obj) {
            var copy = Object.create(Object.getPrototypeOf(obj));
            var propnames = Object.getOwnPropertyNames(obj);
            propnames.forEach(items => {
                let item = Object.getOwnPropertyDescriptor(obj, items);
                Object.defineProperty(copy, items, item)
            })
            return copy;
        }
    
        var a = [{name:'ashen', age: 21}, 1]
        var b = deepClone(a);
        console.log(b)

    注意点:

    数组的slice()方法并不能实现深拷贝

    var a = [1, [1, 2], 3];
    var b = a.slice();
    a[0] = 2;
    console.log(b); // [
    1, [1, 2], 3]
    a[
    1][1] = 1; console.log(b); // [1, [1, 1], 3]
  • 相关阅读:
    ASP.NET的最新安全漏洞Important: ASP.NET Security Vulnerability
    Sql常用日期格式
    倒计时 服务器时间 .NET js javascript
    “备份集中的数据库备份与现有的数据库不同”解决方法
    2010年最佳jQuery插件
    jQuery1.4与json格式兼容问题
    .NET结束外部进程 C#结束外部进程
    十步优化SQL Server中的数据访问
    SQL游标的使用与语法
    SQL2005、SQL2008如何压缩日志文件(log) 如何清除日志
  • 原文地址:https://www.cnblogs.com/ashen1999/p/12732018.html
Copyright © 2011-2022 走看看