首先明确的一点是“赋值”语句不是拷贝(克隆),但是“赋值语句”属于“浅拷贝”,浅拷贝意味着修改一个Object对象({})或者是一个Array(数组对象)时,另外的一个对应的Object对象({})或者是一个Array(数组对象)也会发生相应的改变
下面的代码其实达不到深拷贝的目的,因为,区别是深拷贝还是浅拷贝关键点要通过最开始的数据类型中的数据的类型是引用地址才可以达到判断的目的,举个例子,深浅拷贝是看下面Arr的内容的数据类型,arr = [1, 2,[], {}],也就是在拷贝数据的时候,arr中的[]和{}的是以地址的形式拷贝过去的,还是只是指拷贝[]和{}中的基本数据类型过去的
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>深度克隆(拷贝)实现</title>
<script>
window.onload = function(){
// 创建获取类型的方法
function getType(target){
return Object.prototype.toString.call(target)
}
// 创建克隆的方法
function cloneUtil(target){
// 根据target类型构造最外层具体的数据类型
let result
if(getType(target)==="Object"){
result = {}
}else if(getType(target)==="Array"){
result = []
}else result = target
// 通过for...in....实现遍历
for(let i in target){//这里使用的是for...in...,而没有使用forEach和for...of...,是为了统一使用
// 提取出每一个具体的值:属性值或者是数组的数据
result[i] = target[i] //给Object对象或者是Array对象拷贝内容
}
return result
}
let obj1 = {
name: "张三",
age: 18,
sayName(){
console.log(this)
}
}
let obj2 = cloneUtil(obj1)
obj1.sayName = "王五"
console.log(obj2)
console.log(obj1)
}
</script>
</head>
<body>
</body>
</html>
完整版的深度克隆如下所示
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>深度克隆(拷贝)实现</title>
<script>
window.onload = function(){
// 创建获取类型的方法
function getType(target){
return Object.prototype.toString.call(target).slice(8, -1)
}
// 创建克隆的方法
function cloneUtil(target){
// 根据target类型构造最外层具体的数据类型
let result
if(getType(target) ==="Object"){
console.log("------------")
result = {}
}else if(getType(target)==="Array"){
result = []
}else result = target
// 通过for...in....实现遍历
for(let i in target){//这里使用的是for...in...,而没有使用forEach和for...of...,是为了统一使用
// 提取出每一个具体的值:属性值或者是数组的数据
// 判断要拷贝的值是引用地址还是基本数据类型
let item = target[i]
// console.log(getType(item) === "Object")
if(getType(item) === "Object" || getType(item) === "Array"){
result[i] = cloneUtil(item) //这里其实是一个递归调用,而且,这里的result[i]不能去掉的
}else{
result[i] = item //给Object对象或者是Array对象拷贝内容
}
}
return result
}
let obj1 = {
name: "张三",
age: 18,
sayName: {
option:"男"
}
}
let obj2 = cloneUtil(obj1)
obj1.sayName.option= "王五"
console.log(obj2)
console.log(obj1)
}
</script>
</head>
<body>
</body>
</html>
深度克隆的关键在于,当Object对象或者是Array数据中含有引用数据类型(指定是数组array([])和Object({})),此时在深度克隆时,此处会创建一个新的
而不是,第一个代码中的直接是把原来的旧地址给赋值过去