深拷贝和浅拷贝
对象拷贝包括浅拷贝和深拷贝,修改浅拷贝的对象会影响原对象;修改深拷贝的对象对原对象没有影响。
1、浅拷贝
方式1:对象赋值
新对象变量和原对象变量存储的是相同引用地址,它们指向同一对象,故改变任一对象,另外一对象都会改变。
var person = { name : "Lucy", age : 20, sex : "woman", likeColors : ["white","black"] } var p = person p.age=19; console.log(person.age); //19
方式2:浅拷贝对象
新建对象,遍历原对象的一级属性,赋值给新对象,故改变新对象一级属性不会影响原对象。
但因是浅拷贝,故修改新对象或原对象的任何一对象的非一级属性,都会影响另一对象。
var person = { name : "Lucy", age : 20, sex : "woman", likeColors : ["white","black"] } function shallowCopy(src) { var dst = {}; for (var prop in src) { if (src.hasOwnProperty(prop)) { dst[prop] = src[prop]; } } return dst; } var p = shallowCopy(person); p.age = 19; p.likeColors.push("red"); console.log("p.age="+p.age+" ;p.likeColors="+p.likeColors); console.log("person.age="+person.age+" ;person.likeColors="+person.likeColors); //输出结果:"p.age=19 ;p.likeColors=white,black,red" //输出结果:"person.age=20 ;person.likeColors=white,black,red"
2、深拷贝
方式1:JSON.parse(JSON.stringify(src))
用该方法深拷贝生成的新对象,将过滤掉值为undefined和function类型的属性;且值为RegExp类型的属性,其值将变为空对象。
示例:
function fn(){} var person = { name : "Lucy", age : 20, sex : "woman", likeColors : ["white","black"], weight : null, height : undefined, getWeight : function(){}, getHeight : fn, regExp: /\w+/ } var p = JSON.parse(JSON.stringify(person)); p.age = 19; p.likeColors.push("red"); console.log(p); console.log(person);
执行结果如下图所示:
方式2:递归复制对象的所有属性
function fn(){} var person = { name : "Lucy", age : 20, sex : "woman", likeColors : ["white","black"], weight : null, height : undefined, getWeight : function(){}, getHeight : fn } function isObject(obj){ return obj && !(obj instanceof RegExp) && typeof (obj) == "object" } function deepCopy(src){ var dst = {}; if(Object.prototype.toString.call(src).slice(8,-1).toLowerCase()=="array"){ dst = []; } if(!isObject(src)){ alert("不是对象"); return; } for(var key in src){ dst[key] = isObject(src[key]) ? deepCopy(src[key]) : src[key]; } return dst; } var dp = deepCopy(person); dp.age = 19; dp.likeColors.push("red"); console.log(dp); console.log(person);
执行结果如下图所示: