说克隆之前,首先要说一下,js的数据类型
js中的数据类型分为两大类:原始类型和对象类型。
1)原始类型包括:数值、字符串、布尔值、null、undefined
2)对象类型包括:函数、数组
原始类型存储的是对象的实际数据,而对象类型存储的是对象的引用地址。
克隆的概念
浅度克隆
原始类型为值传递,对象类型仍为引用传递。把一个对象里面的东西复制到另一个对象,新对象原始类型值的修改不会影响到原对象,新对象的对象类型的修改会影响到原对象。
深度克隆
所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。也就是把一个对象里面的东西一模一样地复制到另一个对象,并且这两个对象分别放在内存的不同地方。
浅克隆
var obj = {
name: '张三',
age: 20,
sex: 'female',
address: {
province: 'beijing'
},
favorite: ['red', 'pink']
};
var obj1 = {};
function clone(orgin, target) {
var target = target || {};
for (prop in orgin) {
target[prop] = orgin[prop];
}
}
clone(obj, obj1);
console.log(obj.address.province);
obj1.address.province="shenzhen";
console.log(obj.address.province);
对象类型存储的是对象的引用地址,并不是真实的值,所以当新对象更改时会影响到原对象,在上面的例子中将obj1的address的province属性设置为“shenzhen”,原对象对应的部分也被改变了。
深克隆
为了保证所有的属性都被复制到,我们需要for循环遍历对象,判断是否为原始类型,如果不是继续进行递归,直到得到的元素为原始类型或者函数类型。
var obj = {
name: '张三',
age: 20,
sex: 'female',
address: {
province: 'beijing'
},
favorite: ['red', 'pink']
};
var obj1 = {};
function deepClone(orgin, target) {
var target = target || {};
var tostr = Object.prototype.toString;
var arrstr = "[object Array]";
for (var prop in orgin) {
if (orgin.hasOwnProperty(prop)) {
if (orgin[prop] !== "null" && typeof (orgin[prop]) == 'object') {
if (tostr.call(orgin[prop]) == arrstr) {
target[prop] = [];
} else {
target[prop] = {};
}
deepClone(orgin[prop], target[prop]);
} else {
target[prop] = orgin[prop];
}
}
}
return target;
}
//深度克隆一个对象
deepClone(obj, obj1);
console.log(obj.address.province);
obj1.address.province = "shenzhen";
console.log(obj.address.province);