实现浅克隆
浅克隆概念
1.使用arr1=arr2的语法不会克隆数组(arr1与arr2都是数组,此时arr2与arr1相同,指向同一个地址)。
2.浅克隆:只克隆数组或对象的第一项,如果是多维数组或对象的属性有引用类型值,则不可隆其它层。
3.如何实现浅克隆:
实现浅克隆
准备一个空的结果数组,然后使用for循环遍历原数组,将遍历到的项都推入结果数组
浅克隆只克隆数组的一层,如果数组是多维数组,则克隆项会“藕断丝连”
var arr1= [1,2,3,4,5]
var arr3 = arr1 //没有实现克隆,arr3与arr1仍指向同一个地址
var arr2=[1,2,3,4,[5,6,7]]
var result1=[]
var result2 =[]
// 遍历数组中的每一项,把遍历到的项推入到结果数组中
for(var i=0;i<arr1.length;i++){
result1.push(arr1[i])
}
for(var i=0;i<arr2.length;i++){
result2.push(arr2[i])
}
console.log(result1) //[1,2,3,4,5]
console.log(result1 == arr1) //false,此时实现了克隆,result和arr指向不同的地址(引用类型值==比较的是内存地址)
console.log(result2) //[1,2,3,4,[5,6,7]]
console.log(result2[4]==arr2[4]) //true,藕断丝连,并没有完全分离,实现的是浅克隆
使用for…in…即可实现对象的浅克隆
<script>
var person = {
name:'张三',
age:26,
sex:'男',
job:{
work:'程序员',
salary:15000
}
}
var personClone = {}
for(var k in person){
// 每遍历一个k属性,就给personClone添加一个同名的属性
// 值和person的k属性值相同
personClone[k] = person[k]
}
console.log(personClone) //浅克隆成功 age: 26 job: {work: '程序员', salary: 20000} name: "张三" sex: "男"
console.log(person == personClone) //false
person.name = "李四"
console.log(personClone.name) //张三
person.job.salary = 20000
console.log(personClone.job.salary) //20000
console.log(person.job.salary == personClone.job.salary) //true 藕断丝连
</script>
实现深克隆
深克隆概念
1.深克隆:克隆数组或对象的所有层,需要使用到递归技术
实现深克隆
使用递归的思想,整体思路和浅克隆一样,但稍微进行一些改动;如果遍历到项是基本类型值,则直接推入结果数组;如果遍历到的项又是数组,则重复执行浅克隆的操作。
var arr1 = [3, 2, 4, 1, [12, 10, [11, 16]]]
// 定义一个函数,这个函数会被递归
function deepClone(arr) {
// 定义一个结果数组
// 每一次递归的时候都要生成一个结果数组,所以定义在函数里面
var result = []
// 遍历数组的每一项
for (var i = 0; i < arr.length; i++) {
// 类型判断,如果遍历到的项都是数组
if (Array.isArray(arr[i])) {
// 递归再次遍历数组
result.push(deepClone(arr[i]))
} else {
// 如果遍历到的项不是数组,是基本类型值,就直接推入到结果数组中
// 相当于是递归的出口
result.push(arr[i])
}
}
// 返回结果数组
return result
}
var arr2 = deepClone(arr1)
console.log(arr2)
console.log(arr1[4] == arr2[4]) //false,已经成功克隆,在内存内是不同的地址
以下是对象和数组都包含在一起的深克隆
<script>
var person = {
name:'张三',
age:26,
sex:'男',
job:{
time:"八点",
work:["作家","UI设计师","程序员",{
author:'2000每月',
UIdesiger:'9800每月',
coder:'15000每月'
}]
}
}
function deepClone(o){
// 判断传进来的o是数组还是对象
//这里判断数组和对象的先后顺序不能变,因为用typeof检测数组返回的也是object,所以先检测数组
if(Array.isArray(o)){
// 传进来的是数组
var result = []
for(var i=0;i<o.length;i++){
result.push(deepClone(o[i]))
}
}else if(typeof o == 'object'){
// 传进来的是对象
var result = {}
for(var k in o){
result[k] = deepClone(o[k])
}
}else{
//是基本类型值
var result = o
}
return result
}
var personClone = deepClone(person)
console.log(personClone) //深克隆完全复制过来
console.log(person.job == personClone.job) ///false
console.log(person.job.work == personClone.job.work) //false
person.job.work[3].coder = "30k每月" //更改源的coder值
console.log(personClone.job.work[3].coder) //15000每月
person.job.time = '九点半' //更改源的time值
console.log(personClone.job.time) //八点
</script>