再议js的传递和深复制

病理

基本类型的传递就是按值传递,比如说

    var a = 1;
    var b = a;
    b = 3;
    console.log(a,b);//1,3

很明显,a的值并未因为b的值改变而变化,这是因为a只是给了b一个副本。在这就不详细描述了。下面才是重点

    let obj = {x:1};
    let o = obj;
    o.x = 2;
    console.log(obj.x);//2  已经被改动了

对此我在前面的 js函数参数的传递 中有具体介绍,在这就不多说了。

对症下药

  1. 毛主席说过,遇事莫要急,碰到问题就要解决问题(其实没说过)。知道了是什么原因就好办了,我们把对象直接克隆,也可以叫做深拷贝。

    const deepCopy = function(obj){
        var result = {};
        for(let k in obj){
            result[k] = typeof obj[k]===’object’? deepCoyp(obj[k]): obj[k];
        }
        return result;
    }

    定义一个方法,参数是一个对象obj,然后通过for...in循环获取属性值obj[k],然后将属性值赋值给result中的k属性。其实就是将对象转换为基本类型进行复制了。再试下上面的例子。

    let o = deepCopy(obj);
    o.x = 2;
    console.log(obj.x);// 1

    ok,我们完成复制了。

  2. 以上纯js的办法,当然jquery有一个方法extend(boolean,dest,src1,src2,src3...)可以用来实现对象深层拷贝。第一个参数为true时,表示进行深度拷贝,第二个参数及后面的参数表示将src1,src2,src3...合并到dest中,返回值为合并后的dest。但是这样会使dest的结构发生变化,如果不想修改dest的结构可以将其设为{}。
    let o = $.extend(true,null,obj);
    o.x = 2;
    console.log(obj.x); // 1
  3. 众望所归的es6中的Object.assign()也可以实现深层拷贝。但是es6深复制只有一层,也就是说像obj.a.b=1这种的Object.assign()是不能进行深复制的。下面我们来看代码吧。
    let obj = {
        a : 1,
        b : {
            c : 2
        }
    };
    let result = Object.assign({},obj);
    result.a = 4;
    result.b.c = 3;
    console.log(obj); // {a:1,b:{c:3}}

    这就是assign()方法,比jquery的extend()更容易理解,参数更简单。当然es7中的深层拷贝就更加方便了,这里我就提一下就好了。还是上面的例子吧,直接let obj1 = {...obj,a:4},有没有被惊倒!

    总结

    对于我的问题,选择了extend,因为简单嘛,而且不用转码和考虑兼容性。还有就是碰到问题一定要去debug,这样才能找出原因,然后想办法解决就好了。

时间: 2024-10-08 13:11:04

再议js的传递和深复制的相关文章

再议 js 数字格式之正则表达式

原文:再议 js 数字格式之正则表达式 前面我们提到到了js的数字格式<浅谈 js 数字格式类型>,之前的<js 正则练习之语法高亮>里也提到了优化数字匹配的正则.不过最近落叶给了我一个正则,让我豁然开朗,比我写的犀利多了,所以今天拿出来简单说一下(只说十进制部分的匹配). 先看下我之前写的正则:/\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|\.\d+(?:[eE][+-]?\d+)?/落叶在 jQuery 中发现的正则: /(?:\d*\.|)\d+(?:[eE

也来谈一谈js的浅复制和深复制

1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,undefined,string,number和boolean),这些类型的值本身就存储在栈内存中(string类型的实际值还是存储在堆内存中的,但是js把string当做基本类型来处理 ),不存在引用值的情况. 浅复制和深复制都可以实现在已有对象的基础上再生一份的作用,但是对象的实例是存储在堆内存中然后通

js 对象深复制,创建对象和继承

js 对象深复制,创建对象和继承.主要参考高级编程第三版,总结网上部分资料和自己的代码测试心得.每走一小步,就做一个小结. 1.对象/数组深复制 一般的=号传递的都是对象/数组的引用,如在控制台输入 var a=[1,2,3], b=a; b[0]=0; a[0] 此时显示的结果为0,也就是说a和b指向的是同一个数组,只是名字不一样罢了. 单层深复制: 1.js的slice函数: 返回一个新的数组,包含下标从 start 到 end (不包括该元素,此参数可选)的元素. 控制台输入: var a

js深复制和浅复制

一.关于数组的拷贝 常见问题: let arr = [1, 2, 3, 4]: let arr2 = arr arr2[2] = 10; console.log(arr[2]): // 10 console.log(arr2[2]); //10 很明显我们只想改变arr2的值,保持arr不变,但是事实是两个都会变,这是因为在js中,我们复制对象或者数组实际上只是复制了它的地址,而不是复制的真实的值,这就是我们常说的深复制和浅复制的区别: 深复制:将变量的数据赋值给对应变量 浅复制:将变量的存储地

js中的深复制和浅复制

在实际情况中经常会遇到对对象复制的问题.比如在处理项目中的一笔多结构的数据存储或者调用,这个时候你就要对对象(json)进行操作,而不同的操作根据不同的需求来定义.其中最常见最普遍的是对对象的复制,重新定义,扩展等.下面我们正对这些问题来进行探讨.要了解对象,我们首先需要了解js的内存分配机制: var o = {a:1};当我们在给一个变量赋值的时候已经在浏览器中开辟了一块内存出来.这块内存在浏览器中占了一定的空间,这个时候,我们可以称变量 o 为栈,称{a:1}为堆,他们之间的关系可以用下面

js中对象的复制,浅复制(浅拷贝)和深复制(深拷贝)

在js中,我们经常复制一个对象,复制数据,那么就会有人问了,怎么复制,今天鹏哥就带来js中的复制方法. JS中对象分为基本类型和复合(引用)类型,基本类型存放在栈内存,复合(引用)类型存放在堆内存. 堆内存用于存放由new创建的对象,栈内存存放一些基本类型的变量和对象的引用变量. 至于堆内存和栈内存的区别介绍,你们可以百度看看. 下面开始讲解复制: 这种只是简单的变量,内存小,我们直接复制不会发生引用. var a=123; var b=a; a=123456; alert(a); //1234

实现JS对象深复制的简单方案

前段时间开jQuery源代码的时候,正好看到jQuery.extend的实现方案,忽然想到对象的深复制和浅表复制的问题. 因为引用类型对象的存在,所以简单的使用"="只能实现引用关系的复制,所以当其中一个引用指向的变量发生变化的时候,相应的另外一个引用也会发生变化. 所以很多时候也称这种复制为浅表复制.那么如何才能实现对象的深复制呢?以下是实现深复制的简单实现代码,仅供参考. 1 function copyObject(target){ 2 return _copy(target);

js 深复制一个对象

自定义 cloneObj 方法 //深复制对象 var cloneObj = function (obj) { var newObj = {}; if (obj instanceof Array) { newObj = []; } for (var key in obj) { var val = obj[key]; newObj[key] = typeof val === 'object' ? cloneObj(val) : val; } return newObj; };

js --- 深复制,浅复制

1 //浅复制 2 var obj={ 3 a:{ 4 son1:'aa', //obj对象里的a也是个对象 5 son2:'bb' 6 }, 7 b:20 8 }; 9 10 function copy(obj){ 11 var newobj={}; 12 for(arr in obj) 13 { 14 newobj[arr]=obj[arr] 15 } 16 return newobj; 17 } 18 19 obj2=copy(obj); 20 alert(obj2.a.son1);//成