zoukankan      html  css  js  c++  java
  • 最简js深浅拷贝说明

    1.浅拷贝

      浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。

        浅拷贝分两种情况:

            1、直接拷贝源对象的引用

            2、 源对象拷贝实例,但其属性对象(类型为ObjectArray的属性)拷贝引用

      直接拷贝源对象的引用

    //最简单的例子
    var
    a = {c:1}; var b = a; console.log(a === b); // 输出true。 a.c = 2; console.log(b.c); // 输出 2,,这里就是拷贝了对象的引用,从而两边都改变了

      源对象拷贝实例,其属性对象拷贝引用

      说明:外层源对象是拷贝实例,当其属性元素为复杂数据类型时,内层元素拷贝引用。这时对源对象直接操作,不影响两对象,但是对其属性操作时候,会改变两对象的属性的值。
      常用方法为:Array.prototype.slice()Array.prototype.concat()jQury$.extend({},obj)

    var a = [{c:1}, {d:2},2];
    var b = a.slice();
    console.log(a === b); // 输出false,说明外层数组拷贝的是实例
    a[0].c = 3;
    console.log(b[0].c); // 输出 3,说明其元素拷贝的是引用
    a[2]=4;
    console.log(b[2]); //输出 2,不是复杂数据类型,所以没有变,没有引用

    2.深拷贝

      将重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响。

     深拷贝

    说明:深拷贝后,两个对象,包括其内部的元素互不干扰。常见方法有JSON.parse(),JSON.stringify()jQury$.extend(true,{},obj):

    b = JSON.parse( JSON.stringify(a) )//最简单的深拷贝

      但有局限性:

    • 无法复制函数
    • 原型链没了,对象就是object,所属的类没了

    jQury$.extend(true,{},obj):

    var a = {c: {d: 1}};
    var b = $.extend(true, {}, a);
    console.log(a === b); // 输出false
    a.c.d = 3;
    console.log(b.c.d); // 输出 1,没有改变。

    深拷贝本质理解:将原对象各个属性所包含的对象也依次采用深复制的方法“递归复制”到新对象上。这就不会存在上面 obj 和 shadowObj 的 arr 属性指向同一个对象的问题。例:

    var deepCopy= function(source) { 
    var result={};
    for (var key in source) {
          result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];
       } 
       return result; 
    }//通过递归调用复制对对象上的每一个子类进行复制,从而达到时属性指向不同对象

    复杂全面的代码,可以学习借鉴

    function() {
       function _type(value) {
           return Object.prototype.toString.call(value).slice(8).slice(0, -1).toLowerCase();
       }
    
       function isArray(value) {
           return _type(value) == 'array';
       }
    
       function isObject(value) {
           return _type(value) == 'object';
       }
    
       function cloneArray(src, dest) {
           src.forEach(function(item, index) {
               if (isArray(item)) {
    
    
    
                   console.log('yes')
                   dest[index] = [];
                   copy(src[index], dest[index]);
               } else {
                   dest[index] = src[index];
               }
           });
    
    
       }
    
       function cloneObject(src, dest) {
           for (var key in src) {
               // filter 原型链上面的属性
               if (src.hasOwnProperty(key)) {
                   if (isObject(src[key])) {
                       // 判断循环引用的问题
                       if (src[key] === src) {
                           dest[key] = src;
                       } else {
                           dest[key] = {};
                           copy(src[key], dest[key]);
                       }
                   } else if (isArray(src[key])) {
    
                       dest[key] = [];
                       cloneArray(src[key], dest[key])
    
    
                   } else {
                       dest[key] = src[key];
    
                   }
               }
           }
    
       }
    
    
       function cloneDeep(src) {
           if (isArray(src)) {
               var dest = [];
               cloneArray(src, dest);
           }
           if (isObject(src)) {
    
               var dest = {};
               cloneObject(src, dest);
    
           }
           return dest;
       }
    
    
       window.clone = cloneDeep;
    
    
    })();

    如有错误欢迎留言改正……

    “我相当乐意花一天的时间通过编程把一个任务实现自动化,除非这个任务手动只需要10秒钟就能完成”
  • 相关阅读:
    利用线程池爬虫
    多任务协程怎么写
    利用协程多任务协程爬取前几页投诉网
    cookie的处理和代理池的建立
    bs4和xpath的用法
    怎么使用Ip代理词
    雪球网新闻标题的爬取
    爬虫学习的基础篇
    小说文本爬取
    24 张图彻底弄懂九大常见数据结构
  • 原文地址:https://www.cnblogs.com/flxy-1028/p/6875037.html
Copyright © 2011-2022 走看看