<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>克隆</title>
</head>
<body>
<script>
//浅层克隆
var obj={
name:'abc',
age:123,
sex:'female'
}
var obj1={}
function clone(origin,target){
var target=target||{};//有target就用target,没给target就用自己创建的空对象
for(var prop in origin){
target[prop]=origin[prop];
}
return target;
}
clone(obj,obj1);
// 原始值类型:Undefined、Null、Boolean、Number 和 String 型;存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置;
//引用值类型:object,Array , 函数;存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。
//深度克隆
//引用值不能直接拷贝,不然拷贝的是地址
//无论原始值还是引用值都是各自独立的了,改一个不会影响被克隆的或者克隆的值
//遍历对象 for(var prop in obj) for in方法可以用于对象也可用于数组
//1:判断是不是原始值,typeof() 看结果是否为objec则为引用值 原始值直接拷贝
//2:如果是引用值,判断是数组还是对象 instanceof toString constract
//3:建议相应的数组或对象
//递归 比如如果引用值里面还包含了引用值,就要用递归循环判断里面的值是原始值还是数组,对象
//以下代码为逻辑分析
var obj={
name:'abc',
age:123,
card:['visa','master'],
wife:{
name:"bcd",
son:{
name:"aaa"
}
}
}
var obj1={
name:"abc",
age:123,
card:[obj.card[0],obj.card[1]],//数组里面是原始值
wife:{
name:"bcd",
// son:
}
}
//代码怎么写呢?
function deepClone(origin, target) {
var target = target || {},
toStr = Object.prototype.toString,
arrStr = "[object Array]";
for (var prop in origin) {
if (origin.hasOwnProperty(prop)) { //判断是否是原型的值,是原型的则不拷贝
if (origin[prop] !== "null" && typeof (origin[prop]) == 'object') { //!==绝对不等于,防止隐式类型转换
if (toStr.call(origin[prop]) == arrStr) {
target[prop] = [];
} else {
target[prop] = {};
}
deepClone(origin[prop], target[prop]); //递归
} else {
target[prop] = origin[prop];
}
}
}
return target;
}
deepClone(obj, obj1)
</script>
</body>
</html>
arrStr的值
如果不深度克隆,给拷贝的对象添加新属性会影响到原始对象
使用深度拷贝互相没影响