作为一个程序猿,相信对于拷贝这个知识点不会陌生,面试的时候面试官应该也可能会问到这个问题吧,写这个也是为了方便以后回顾。
1.浅拷贝
概念:浅拷贝仅仅复制了对象的引用,而不是对象本身。
方法一:直接上
function simpleClone(initalObj) {
var obj = {};
for ( var i in initalObj) {
obj[i] = initalObj[i];
}
return obj;
}
方法二:Object.assign()
2.深拷贝
概念:把复制的对象所引用的全部对象都深拷贝一遍。
方法一:JSON.parse()方法。
function deepClone(initalObj) {
var obj = {};
try {
obj = JSON.parse(JSON.stringify(initalObj));
}
return obj;
}
注意:
one varjsonStr1 = '{sex:"男",info:"我是好人"}';
two varjsonStr2 = "{'sex':'男','info':'我是好人'}";
three varjsonStr3 = '{"sex":"男","info":"我是好人"}';
只有第三种情况才能使用JSON.parse,另外注意一下eval这个函数,如果jsonString是可执行的一段代码,那eval则会直接执行这句代码,故能不用就不用。
方法二:递归拷贝
function deepClone(initalObj, finalObj={}) {
var obj = finalObj;
for (var i in initalObj) {
var prop = initalObj[i];
// 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if(prop === obj) {
continue;
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : {};
arguments.callee(prop, obj[i]);
} else {
obj[i] = prop;
}
}
return obj;
}
注意:这里用到了arguments.callee,arguments.callee等同于调用自己,这样写,相当于不管自己函数名是什么,都会调用这个函数。但是,arguments在现在的浏览器中是建议少使用,arguments会影响性能。故,请择优使用。
另附:
function clone(obj) {
var o;
if(typeof obj =="object") {
if(obj ===null) {
o =null;
}else{
if(objinstanceofArray) {
o = [];
for(vari =0,len = obj.length;i < len;i++) {
o.push(clone(obj[i]));
}
}else{
o = {};
for(varjinobj) {
o[j] =clone(obj[j]);
}
}
}
}else{
o = obj;
}
return o;
}
再附:jquery的extend() http://link.funteas.com/?target=https%3A%2F%2Fgithub.com%2Fjquery%2Fjquery%2Fblob%2Fmaster%2Fsrc%2Fcore.js