本人小白,初接触JS在此,仅仅是将自己学到的认识到的,写在这里做个笔记。
在JS中赋值的主要有两种类型:
(1)直接将数值类进行复制
(2)引用赋值,如下:
1 var obj = { 2 name:'xx' 3 } 4 5 var o1 = obj1; 6 var o2 = o1;
当我们修改o2.name 那么o1.name会随之发生改变。

上述情况就说明o1,o2指向的是同一块内存区域。o1,o2拥有的只是一种类似指针的东西指向同一块内存区域。
那么来看看JS的复制。
(1)浅复制,在复制JS中‘object’,'array' 这类型的属性时,只是简单的复制引用,当我们的原始对象发生改变时,克隆过后的对象会跟着发生改变。类似与上面的情况。
1 function shallowClone(obj){ 2 var newObj = {}; 3 for(var attr in obj){ 4 if(obj.hasOwnProperty(attr)){ 5 newObj[attr] = obj[attr]; 6 } 7 } 8 return newObj; 9 }
当我们尝试修改克隆对象时,会看到如下结果:
var obj = {a:1,arr:[2,3]}; var shallowObj = shallowClone(obj); shallowObj.arr[0]=3;

在ES6中,定义了一个方法Object.assign(..)。
第一个参数为目标对象target,后续的参数是一个或者多个源对象source。它会在源对象上迭代所有可枚举的,直接拥有的的key,将他们拷贝到目标对象(target)上。并且返回目标对象。
所以,当我们操作JS对象,对其进行拷贝时,一定要注意,有可能你一不小心用到了浅复制,难么你在修改任何一个copy的时候会操成所有的copy发生改变。
(2)深复制,相对于浅复制来说,深复制是在浅复制的基础上,将被copy对象上的所有‘object’,'array'再进行一次浅复制。
1)一种实现方式是采用JSON序列化、反序列化来实现。
if(Window.JSON){ str = JSON.stringify(obj)//序列化对象 newObj = JSON.parse(str);//还原 }
这种方式必须保证对象是可以系列化成JSON的。
2)在浅复制的基础上,当我们碰到'object"、“array”类型的数据,我们采用递归。
var parentObject = []; function deepCopy(obj){ var str,newObj = obj.constructor ===Array ? []:{} parentObject.push(obj) if (typeof obj != 'object'){ return ; }else{ for (var i in obj){ var v = obj[i] if(parentObject.indexOf(v) > -1){ throw Error("检测到循环引用") }else{ newObj[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]):obj[i]; } } } parentObject.pop(); return newObj; }
此时,当我们再修改一个copy时,不会对原对象造成影响了。
var newO = deepCopy(myObject); newO.b.c = false;

上述的两种深复制方法都有缺陷,不能解决循环依赖的问题。方法二只能做出检测,方法一会直接堆栈益处。
循环依赖如下:
function antherFunction(){}; var antherObject = { c:true }; var antherArray = []; var myObject = { a:2, b:antherObject, c:antherArray, d:antherFunction }; antherArray.push(antherObject,myObject);
浙公网安备 33010602011771号