zoukankan      html  css  js  c++  java
  • 每日技术:浅复制和深复制,slice()

    前言:学习不是一件容易的事。加油~

    浅复制和深复制

    一直对浅复制(也叫浅拷贝)和深复制(也叫深拷贝)这两个概念不清楚。

    深复制和浅复制只针对Object,Array这样复杂的对象。

    以下参考:https://www.jianshu.com/p/0d7bd31ccf43

    深复制和浅复制最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用。

    深复制在计算机中开辟了一块内存地址用于存放复制的对象

    浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变

    所谓的浅复制,只是拷贝了基本数据类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做浅复制。

    以下内容来自知乎 邹润阳的回答

    一个简单的浅复制实现:

    var obj = {
        a: 1,
        arr: [2, 3]
    }
    var shallowObj = shallowCopy(obj)
    
    function shallowCopy(src) {
        var dst = {};
        for (var prop in src) {
            if (src.hasOwnProperty(prop)) {
                dst[prop] = src[prop]
            }
        }
        return dst;
    }

    因为浅复制只会将对象的各个属性进行一次复制,并不会进行递归复制

    而深复制则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在数组对象属性指向同一个对象的问题

     以下内容参考:https://segmentfault.com/q/1010000006865450

    浅复制举例代码:

    Array.clone = function(arr) {
        const ans = [];
        for(let i = 0; i < arr.length; i++) {
            ans[i] = arr[i];
        }
        return(ans);
    }
    
    let a = [1,2,3,[4,5,6],[7,8,9]],
        b = Array.clone(a);
    
    console.log(a === b);            //false
    console.log(a[3]);               //[4,5,6]
    console.log(a[3] === b[3]);      //true
    console.log(a[4] === b[4]);      //true

    深复制举例代码:

    Array.clone = function(arr) {
        const ans = [];
        for(let i = 0; i < arr.length; i++) {
            if(arr[i].length) {
                ans[i] = Array.clone(arr[i]);
            } else {
                ans[i] = arr[i];
            }
        }
        return(ans);
    }
    
    let a = [1,2,3,[4,5,6],[7,8,9]],
        b = Array.clone(a);
    
    console.log(a === b);            //false
    console.log(a[3]);               //[4,5,6]
    console.log(a[3] === b[3]);      //false
    console.log(a[4] === b[4]);      //false

     关于深浅复制的笔记写得非常散乱,没办法,感觉不是很好懂。就酱先。 

    Array.prototype.slice()

    slice()方法返回一个新的数组对象,这一对象是一个由begin和end决定的原数组的浅拷贝(包括begin,不包括end)。原始数组不会被改变。

    怎么理解这里说的浅拷贝?(为了理解这一点才有了上面的浅复制和深复制的学习内容)

    列举一段简单的代码:

    var arr0 = [1, 9, [2, 3], [4, 5]];
    
    var arr1 = arr0.slice(1);
    console.log(arr1);
    // [9, [2, 3], [4, 5]]
    
    console.log(arr1[1] == arr0[2]);
    // true

    这里说的浅拷贝是针对数组对象成员的浅拷贝

    深拷贝和浅拷贝的概念是针对Object,Array这种复杂的引用型数据类型而言的。

    Array.from()

    Array.from()方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历的(iterable)的对象

    利用Array.from()方法复制一个数组

    var arr1 = [1, [1, 2], 3]
    var arr2 = Array.from(arr1);
    console.log(arr1 === arr2);
    // false
    console.log(arr1[1] === arr2[1]);
    // true

    可见对于数组成员该方法返回的是浅拷贝的结果。

    常见的类数组对象有:

    • DOM操作返回的NodeList集合
    • 函数内部的arguments对象
  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/cathy1024/p/11264476.html
Copyright © 2011-2022 走看看