精华内容
下载资源
问答
  • JS深拷贝和浅拷贝

    千次阅读 2021-01-21 23:01:40
    深拷贝是重新开辟一块内存空间,用来存放sources对象的值。 浅拷贝可以用for in 来实现,也可用es6新增方法Object.assign(target,...sources) 来实现,target为目标对象,sources为原对象(要进行拷贝的对象) 浅...

     

    1. 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。
    2. 浅拷贝是拷贝的内存地址,使新对象指向拷贝对象的内存地址。深拷贝是重新开辟一块内存空间,用来存放sources对象的值。
    3. 浅拷贝可以用for in 来实现,也可用es6新增方法Object.assign(target,...sources) 来实现,target为目标对象,sources为原对象(要进行拷贝的对象)
    4. 浅拷贝后改变target中的值,sources也会进行改变。深拷贝不会这样
    5. 深拷贝可以基于函数封装的方法来进行实现。
    <body>
        <script>
            var obj = {
                id: 1,
                name: 'andy',
                msg: {
                    age: 18
                }
            };
            var o = {};
            var j = {};
            function shallowCopy(newobj, oldobj) {
                for(var k in oldobj){
                    newobj[k] = old[k];
                }
            }
            shallowCopy(o, obj);
            console.log('o',o)
            o.id = 2;
            console.log('obj',obj)
            //封装深拷贝函数
            function deepCopy(newobj, oldobj) {
                for (var k in oldobj) {
                    //判断属性值属于那种数据类型
                    //1.获取属性值 old[k]
                    var item = oldobj[k];
                    //2. 判断这个值是否是数组
                    //必须先判断是否是Array 因为Array 也是Object
                    if(item instanceof Array){
                        newobj[k] = [];
                        deepCopy(newobj[k], item);
                    }else if(item instanceof Object){
                        //3.判断这个值是否是对象
                        newobj[k] = {};
                        deepCopy(newobj[k], item);
                    } else {
                        //4.属于简单数据类型
                        newobj[k] = item;
                    }
                }
            }
            deepCopy(j,obj);
            console.log('j',j);
            j.id = 4;
            console.log('obj',obj);
        </script>
    </body>

    存在不足之处可随时补充。

    学习地址

    展开全文
  • 所谓深拷贝与浅拷贝,乍一听我也蒙了,仔细一看其实就是C#中值类型复制和引用类型复制的区别。深拷贝就是引用类型复制时不仅仅将引用复制,同时还将数据复制了一份,从而得到了liang'gen

    所谓深拷贝与浅拷贝,乍一听我也蒙了,仔细一看其实就是C#中值类型复制和引用类型复制的区别。

    值类型自然不存在这个概念,因为你怎么复制都是两个数据,但是引用类型就不一样了,引用类型涉及到引用的复制和值的复制问题。因此下面没有提到数据类型时候都是在说引用类型哈!

    深拷贝就是引用类型复制时不仅仅将存在栈中的引用复制,同时还将堆中的数据复制了一份,从而得到了两份数据。

    浅拷贝就是平常的赋值方式,仅仅将栈中的引用复制了,但是堆中的数据并没有复制。

    【值类型数据放在栈中;引用类型数据在堆中,引用在栈里】


    1.引用类型中常见的深拷贝方式

    ①数组:采用es6的...展开

        let a=[1,2,3],

        let b=[...a];

    ②json:采用es6的...展开

        let a={"c":12};

        let b={...a};

    ③系统对象

        Date等,直接将其实例作为新对象创建过程中构造函数的参数即可【因为系统对象已经帮你实现了这个过程】

        let a=new Date();

        let b=new Date(a);

        这样b就对a实现了深拷贝

    ④自定义对象

         与系统对象方式一样,但是前提你要自己写拷贝方法。

    ⑤symbol类型

        有关symbol内容请看:https://es6.ruanyifeng.com/#docs/symbol

         symbol类型的深拷贝要利用symbol.for进行,同时利用ES2019 提供了一个实例属性description,直接返回 Symbol 的描述。

          let s1=symbol.for('wayne');

          let s2=symbol.for(s1.description);

    这样s2就实现了对s1的深拷贝。

    2.完整深拷贝通用代码

            //[4]深拷贝方法
    	function clone(data){
    		//1.判断symbol类型
    		if (typeof data=="symbol"){
    			return symbol.for(data.description);
    		}
    		//2.判断值类型(即不是object类型)
    		else if (typeof data!="object"){
    			return data;
    		}
    		//3.判断数组
    		else if (data.constructor===Array){
    			return data.map(i=>clone(i));
    		}
    		//4.判断json类型
    		else if (data.constructor===Object){
    			let tem={};
    			for(let key in data){
    				tem[key]=clone(data[key]);
    			}
    			return tem;
    		}
    		//5.判断系统对象和自定义对象
    		else{
    			return new data.constructor(data);
    		}
    	}

    注意,对于数组和json格式来说,单纯的...展开只能实现一层的拷贝,如果想多层拷贝,就要用到上述代码中3和4所写的那样,利用递归。

    3.总结

    目前针对深拷贝浅拷贝就这么多,欢迎留言指正讨论

    展开全文
  • 手写js深拷贝

    2021-04-20 16:40:32
    // 定义一个深拷贝方法 function deepClone(obj = {}){ // 判断传入的数据是否是引用类型(一般为对象或者数组) if(typeOf obj !== 'object' || obj == null){ // 如果不是,那么返回该数据 return obj; } //...
    // 定义一个深拷贝方法
    function deepClone(obj = {}){
    	// 判断传入的数据是否是引用类型(一般为对象或者数组)
    	if(typeOf obj !== 'object' || obj == null){
    		// 如果不是,那么返回该数据
    		return obj;
    	}
    	// 定义一个拷贝后的结果,用来当返回值
    	let result;
    	// 判断结果值为数组还是对象
    	if(obj instanceOf Array){
    		result = []
    	}else{
    		result = {}
    	}
    	// 遍历传入的对象,并赋值
    	for(let key in obj){
    		// 判断是否为自己本身的属性
    		if(obj.hasOwnProperty(key)){
    			// 如果是,赋值(递归复制深层)
    			result[key] = deepClone(obj[key])
    		}
    	}
    	// 返回结果数据
    	return result
    }
    

    注意:
    1、typeOf obj !== 'object'判断时,object的o一定为小写;
    2、obj == nullobj === null || obj === undefined的简写;
    3、for…in和for…of的区别:
    for…in:(1)es5标准,遍历的是key;(2)遍历数组无序;(3)会遍历出原型属性;(4)兼容性:IE9以下不兼容;(建议用来遍历对象)
    for…of:(1)es6标准,遍历的是value;(2)遍历数组有序,并且可执行continue,break和return;(3)不会遍历出原型属性;(4)兼容性:IE不支持;(建议用来遍历数组);

    展开全文
  • js深拷贝

    2021-04-09 08:59:32
    true new.constructor === Object // true (二) 递归实现深拷贝 const deepClone = () => { if (typeof obj !== 'object' || obj === null) return obj; if(obj.constructor === Date) return new Date(obj); if...

    (一) 先来看下有点问题的写法

    // JSON.parse()与JSON.stringify()
    
    const clone = function (obj) {
        return JSON.parse(JSON.stringify(obj));
    }
    

    这种方法只适用于纯数据json对象的深度克隆,缺陷参考如下代码:

    const clone = function (obj) {
        return JSON.parse(JSON.stringify(obj));
    }
    let a = {a:function(){console.log('hello world')},b:{c:1},c:[1,2,3],d:"jj",e:new Date(),f:null,g:undefined}
    let b = clone(a)
    console.log(b)
    // 结果
    b: Object { c: 1 }
    c: Array(3) [ 1, 2, 3 ]
    d: "jj"
    e: "2021-04-09T01:22:24.379Z"
    f: null
    

    上述的方法会忽略值为function以及undefined的属性,而且对date类型的支持也不太友好。

    更要紧的是,上述方法只能克隆原始对象自身的值,不能克隆它继承的值,参考如下代码:

    function Person (name) {
        this.name = name
    }
    var old = new Person('jj')
    var new = clone(old)
    old.constructor === Person // true
    new.constructor === Object // true
    

    (二) 递归实现深拷贝

    const deepClone = () => {
      if (typeof obj !== 'object' || obj === null) return obj;
      if(obj.constructor === Date) return new Date(obj); 
      if(obj.constructor === RegExp) return new RegExp(obj);
      // let newObj = obj instanceof Array ? [] : {};
      let newObj = new obj.constructor(); // 保持继承链
    
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) { // 不遍历其原型链上的属性
          // newObj[key] = arguments.callee(obj[key]); // 使用arguments.callee栈溢出
          newObj[key] = deepClone(obj[key]);
        }
      }
      return newObj;
    }
    
    展开全文
  • js 深拷贝

    2020-12-21 13:39:15
    JS深拷贝 由于基本数据类型一般存储在栈中,而引用类型栈中只存储了一个引用,真正的内容存储在堆中 比如我们对一个基本类型进行赋值 var a = 1 var b = a a = 3 console.log(a) //3 console.log(b) //1 我们发现...
  • 1、为什么会有深拷贝浅拷贝区别? 因为引用数据类型和基本数据类型的存储方式不同,因而有了深浅拷贝之分。基本类型直接存放在栈内存中,而引用类型栈内存中存放的是该对象在堆内存的起始地址,真正数据是存放在堆...
  • JS深拷贝

    2021-03-08 18:24:33
    简化版只拷贝对象: var a1 = { name: 'zhang3', age: 18, sex: 'man', children: { name: 'zhang4', age: 18, sex: '' } } function DeepCopy(Origin) {
  • 本版本的深拷贝考虑了Symbol作为对象属性的情况(Symbol相关介绍看这:Symbol)。 由于引用类型在赋值时只传递指针,这种拷贝方式称为浅拷贝。 而创建一个新的与之相同的引用类型数据的过程称之为深拷贝。 在...
  • JS深拷贝对象f 代码如下(示例): export function deepCopy(obj) { var objClone = Array.isArray(obj) ? [] : {}; if (obj && typeof obj === "object") { for (var key in obj) { if (obj....
  • JS 深拷贝的三种实现方式1、将对象转换为JSON字符串形式,再将其转换为原生JS对象;//_tmp和result是相互独立的,没有任何联系,有各自的存储空间。let deepClone = function (obj) {let _tmp = JSON.stringify(obj)...
  • 换成js代码就变成了基本数据类型和引用数据类型的拷贝。 在JavaScript中我们定义的简单数据类型会存到栈(stack)内存中,包括引用类型的指针,而这个指针指向的地方是在堆(heap)内存中。也通常理解为,简单数据类型...
  • 关于深拷贝和浅拷贝的概念和区别在这里就不再赘述了, 而常规的JSON.parse(JSON.stringfy(data)方式存在很多缺陷,例如无法处理undefined、function、特殊引用类型、循环引用等。 最近尝试手写一下深拷贝的实现,...
  • 深拷贝 JSON.parse(JSON.stringify(obj))深拷贝已有对象 JSON.stingify(obj)将js中的对象转换成JSON字符串 let jack = { name: 'jack' } console.log(jack) console.log(JSON.stringify(jack)) 它们在格式上有...
  • 结合实际工作场景深入理解Javascript深拷贝和浅拷贝的特性,Javascript深拷贝,浅拷贝理解,数组、对象实现设深拷贝的不同方式
  • JavaScript 对象深拷贝,嵌套对象处理 可以使用 ES6 的 WeakMap 将对象保存起来,循环中遇到相同对象直接指向已经存在的对象即可 WeakMap 对象是一组键值对的集合,其中的键是弱引用的,其键必须是对象,而值可以是...
  • 目录 1. API简介 2. 基本使用 3. 拷贝函数 4. 指定拷贝深度 5. 循环引用 6. 保持类型信息 ...9. 创建带预设拷贝规则的拷贝函数 内容 1. API简介 deep-copy 导出了两个工具函数 import {deepCopy
  • 方法一: 使用JSON转换 function deepClone2(target) { //通过数据创建JSON格式的字符串 let str = JSON.stringify(target... //将JSON字符串转化为JS数据 let data = JSON.parse(str); return data; } ...
  • js 深拷贝和浅拷贝

    2021-03-18 15:12:29
    JS中数据类型 基本数据类型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用数据类型: Object(Array, Date, RegExp, Function) 深浅拷贝 深浅拷贝只是针对引用类型的,因为引用类型是存放在堆...
  • 前言 最近遇到一个需求,keep-alive 缓存 list 组件...我想到的是利用 JS 深拷贝去实现。 数据深拷贝 判断数据类型 // 检查属性类型 checkType (any) { return Object.prototype.toString.call(any).slice(8, -1) },
  • 深拷贝与浅拷贝的简单区分: 假设B复制了A,当修改A时,看B是否跟着改变: 若B也跟着改变,说明是浅拷贝; 若B没有变化,说明是深拷贝。 注意:一般情况下,深拷贝只针对较为复杂的object类型数据。 js数据类型 js中...
  • JS深拷贝与浅拷贝

    2021-05-09 18:30:53
    一、如何简单区分深拷贝与浅拷贝 用语言描述,假设B复制了A,然后修改A,当修改A时,B发生了变化,说明这就是浅拷贝,若是B没有发生变化,就是深拷贝 二、JS基本数据类型与与引用数据类型数据存储 1、基本数据类型...
  • 实现js深拷贝

    2021-11-04 14:34:22
    最简单的办法可以使用: JSON.parse(JSON.stringify()); 但如果是面试时碰见这种问题,这样回答肯定是不行的,换一种思路,我们自己...到这里其实也只考虑了Array和Object,但更层次的就会更复杂,这里也不做详述了
  • 如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。1. 如果是基本数据...
  • js深拷贝、深克隆

    2021-01-19 14:41:21
    js深拷贝 上篇文章,我们看到的其实就是简单的浅拷贝。 一、 浅拷贝 对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会使得所有对象的值修改,...
  • 浅析JS深拷贝

    2021-04-17 13:35:23
    浅析JS深拷贝 常用的拷贝方案: JSON.parse(JSON.stringfily()) Object.assign() Object.create() JSON.parse(JSON.stringfily())分析 const obj = { a: 1, b: '1', c: false, d: null, e: undefined, f: /\...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,561
精华内容 18,224
关键字:

js深拷贝

友情链接: 红外扫码.rar