zoukankan      html  css  js  c++  java
  • 再议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,我们完成复制了。

    1. 以上纯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
      
    2. 众望所归的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,这样才能找出原因,然后想办法解决就好了。

  • 相关阅读:
    java--exceptions
    java-interface
    Java笔记
    memcpy
    const 关键字
    LeeCode整数 反转
    函数调用运算符笔记
    cvCreateImage
    c++继承笔记1
    虚拟机下的debian无法登陆
  • 原文地址:https://www.cnblogs.com/open-wang/p/5807986.html
Copyright © 2011-2022 走看看