病理

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

    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,这样才能找出原因,然后想办法解决就好了。

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

  1. 一文带你了解js数据储存及深复制(深拷贝)与浅复制(浅拷贝)

    背景 在日常开发中,偶尔会遇到需要复制对象的情况,需要进行对象的复制. 由于现在流行标题党,所以,一文带你了解js数据储存及深复制(深拷贝)与浅复制(浅拷贝) 理解 首先就需要理解 js 中的数据类型 ...

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

    原文:再议 js 数字格式之正则表达式 前面我们提到到了js的数字格式<浅谈 js 数字格式类型>,之前的<js 正则练习之语法高亮>里也提到了优化数字匹配的正则.不过最近落叶 ...

  3. js对象或数组深复制

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

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

    js 对象深复制,创建对象和继承.主要参考高级编程第三版,总结网上部分资料和自己的代码测试心得.每走一小步,就做一个小结. 1.对象/数组深复制 一般的=号传递的都是对象/数组的引用,如在控制台输入 ...

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

    1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...

  6. js的浅复制和深复制

    1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...

  7. js中的深复制与浅复制

    前言 所谓深复制与浅复制(深拷贝与浅拷贝),乍一听感觉听高大上,像是一个非常难理解的概念,其实我们平常项目开发都是在用的,只是你可能不知道该怎么叫它的名字而已,就像你听熟了一首歌,就是不知道这首歌叫什 ...

  8. js中的深复制和浅复制

    在实际情况中经常会遇到对对象复制的问题.比如在处理项目中的一笔多结构的数据存储或者调用,这个时候你就要对对象(json)进行操作,而不同的操作根据不同的需求来定义.其中最常见最普遍的是对对象的复制,重 ...

  9. js深复制

    一般来讲深复制主要是为了复制js对象中的引用类型,引用类型在普通的赋值操作下相当于是引用,修改复制对象也会影响原对象,简单的方法的话可以使用JSON.parse(JSON.stringify(obj) ...

随机推荐

  1. 获取assets文件内容,raw内容

    1.均采用流的方式获取里面的内容 assets context.getAssets().open(“fileName”); raw InputStream inputStream = context. ...

  2. SpringCloud (十) Hystrix Dashboard单体监控、集群监控、与消息代理结合

    一.前言 Dashboard又称为仪表盘,是用来监控项目的执行情况的,本文旨在Dashboard的使用 分别为单体监控.集群监控.与消息代理结合. 代码请戳我的github 二.快速入门 新建一个Sp ...

  3. c++模板函数作为参数的疑惑

    为什么22行只能传一个模板函数作为参数,而非模板却编译失败,求解释.

  4. Linux基础-free窥内存-dd探硬盘

    监控内存篇(RAM)-free free指令可以很直观的看到内存的使用情况 free -m指令以单位为MB的方式查看内存的使用情况(free命令读取的文件是/proc/meminfo) 这个表格的解释 ...

  5. ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer::ComputeF21 (OpenCV 细节)

    ORB_SLAM2 计算 F21 的代码是这样的. cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1,c ...

  6. 使用vue的一些经验

    虽然说VUE是数据驱动视图的框架,但有时候不得不获取DOM来获得一些样式属性,做一些操作,这时候就需要VUE获取DOM对象的方法. vue获取DOM对象的方法: 如果是操作组件内部的DOM,可以通过给 ...

  7. MongoDB以Windows Service运行

    以Administrator身份打开CMD并输入以下命令 cd D:\Developer\MongoDB\mongodb-win32-x86_64-2.4.6\binD:mongod --logpat ...

  8. 【TortoiseSVN】windows中连接SVN服务器的工具

    1.下载安装包: 可以到我的服务器地址进行下载,有32和64位的安装包: http://qiaoliqiang.cn/fileDown/TortoiseSVN-1.8.8.25755-win32-sv ...

  9. angular select ng-change实时获取value

    <select ng-model="vm.selectVal" ng-options="o.id as o.title for o in vm.optionsDat ...

  10. JDK1.8源码之String

    一.String类型 引用博文连接:  https://blog.csdn.net/ylyg050518/article/details/52352993 一.成员变量 //用于存储字符串 priva ...