深浅拷贝与f/in

阅读: 评论:0

深浅拷贝与f/in

深浅拷贝与f/in

📝 个人简介

⭐ 个人主页:我是段段🙋‍
🍊 博客领域:编程基础、前端💻
🍅 写作风格:干货!干货!都是干货!
🍑 精选专栏:数组
🛸 支持段段:点赞👍、收藏⭐、留言💬

深浅拷贝与for…of/in

for…of与for…in

for…of是ES6新增的遍历方式,允许遍历一个含有Iterator接口的数据结构并且返回各项的值

具有原生Iterator接口的数据结构

Array
Map
Set
TypeArray
类数组对象(函数的arguments对象、NodeList对象)...

可见Object没有部署原生的Iterator接口,所以不能使用for…of进行循环

遍历Object

let obj = {a: 1,b: 2,c: 3
}// in
for(let key in obj){console.log(key) // a b c
}// f
for(let key of obj){console.log(key) // obj is not iterable
}

遍历Array

let arr = [4, 5, 6]// in
for(let prop in arr){console.log(prop) // 0 1 2
}// f
for(let prop of arr){console.log(prop) // 4 5 6
}

深浅拷贝

数据类型分为 基本数据类型引用数据类型

  1. 基本数据类型
  • 主要包括:String、Number、Boolean、Null、Undefined、Symbol(ES 6)

  • 其特点为:直接存储在中的数据

  1. 引用数据类型
  • 主要包括:Object 、Array 、Date 、Function,统称为Object类型

  • 其特点为:存储的是该对象在栈中引用,真实的数据存放在堆内存

拷贝分为浅拷贝和深拷贝,其二者都是针对Object和Array类型的

浅拷贝只复制指向某个对象的指针而不复制对象本身,新旧对象还是共享同一块内存,修改新对象也会修改到原对象

深拷贝则会另外创建一个新的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象

对象深/浅拷贝

当对象中包含复杂数据类型时

// 对象中包含复杂数据类型
let obj = {username: '猪八戒',sex: '雄性',age: 800,hobby: ['翠兰', '高老庄']
}// 浅拷贝
let newObj = {}
for(let prop in obj){newObj[prop] = obj[prop]
}
newObj.hobby.push('吃')
console.log(newObj, 'newObj')
console.log(obj, 'obj')
// { username: '猪八戒', sex: '雄性', age: 800, hobby: [ '翠兰', '高老庄', '吃' ] } newObj
// { username: '猪八戒', sex: '雄性', age: 800, hobby: [ '翠兰', '高老庄', '吃' ] } objlet newObj = {}
newObj = { ...obj }
newObj.hobby.push('吃')
console.log(newObj, 'newObj')
console.log(obj, 'obj')
// { username: '猪八戒', sex: '雄性', age: 800, hobby: [ '翠兰', '高老庄', '吃' ] } newObj
// { username: '猪八戒', sex: '雄性', age: 800, hobby: [ '翠兰', '高老庄', '吃' ] } obj
// 可以看出浅拷贝时,新对象和原对象中的数据都发生了变化

当对象中不包含复杂数据类型时

// 深拷贝(单层)
// 不包含复杂数据类型
let obj1 = {name: '张三',age: 24
}// 使用Object.assign()方法
let obj2 = Object.assign({}, obj1)
obj2.age = 22
console.log(obj1)
console.log(obj2)
// { name: '张三', age: 24 }
// { name: '张三', age: 22 }// ..扩展运算符
let obj2 = { ...obj1 }
obj2.age = 22
console.log(obj1)
console.log(obj2)
// { name: '张三', age: 24 }
// { name: '张三', age: 22 }// 循环遍历对象
let obj2 = {}
for(let key in obj1){obj2[key] = obj1[key]
}
obj2.age = 22
console.log(obj1)
console.log(obj2)
// { name: '张三', age: 24 }
// { name: '张三', age: 22 }

当对象中包含复杂数据类型的多层深拷贝

let obj = {username: '猪八戒',sex: '雄性',age: 800,hobby: ['翠兰', '高老庄'],monster: {name: ['白骨精', '豹子精']}
}let newObj = {}
for(let prop in obj){newObj[prop] = obj[prop]
}
ster.name.push('蛇精')
console.log(newObj, 'newObj')
console.log(obj, 'obj')
// {
//   username: '猪八戒',
//   sex: '雄性',
//   age: 800,
//   hobby: [ '翠兰', '高老庄' ],
//   monster: { name: [ '白骨精', '豹子精', '蛇精' ] }
// } newObj
// {
//   username: '猪八戒',
//   sex: '雄性',
//   age: 800,
//   hobby: [ '翠兰', '高老庄' ],
//   monster: { name: [ '白骨精', '豹子精', '蛇精' ] }
// } obj
// 深拷贝(多层)
let newObj = deepClone(obj)
newObj.hobby.push('吃')
console.log(newObj, 'newObj')
console.log(obj, 'obj')
// { username: '猪八戒', sex: '雄性', age: 800, hobby: [ '翠兰', '高老庄', '吃' ] } newObj
// { username: '猪八戒', sex: '雄性', age: 800, hobby: [ '翠兰', '高老庄' ] } obj
// 深拷贝时,只有新的对象中添加了数据,没有改变原始对象中的数据// 封装一个函数,用来实现Object类型的深拷贝
function deepClone(o){if(o instanceof Array){let _arr = []for (var i = 0, len = o.length; i < len; i++) {_arr[i] = typeof o[i] === 'object' ? deepClone(o[i]) : o[i]}return _arr} else if(o instanceof Object){let _o = {}for(let key in o){_o[key] = typeof o[key] === 'object' ? deepClone(o[key]) : o[key]}return _o}return o
}

数组深/浅拷贝

let arr = [1, 2, 3]
// 浅拷贝
let newArr = arr
newArr.push(4)
console.log(arr)
console.log(newArr)// [ 1, 2, 3, 4 ] arr
// [ 1, 2, 3, 4 ] newArr
// 和浅拷贝对象时一样,新数组和原数组都发生了变化
// 深拷贝(单层)
// 循环遍历的方法
let newArr = []
arr.forEach( item => {newArr.push(item)
})
newArr.push(4)
console.log(arr, 'arr')
console.log(newArr, 'newArr')
// [ 1, 2, 3 ] arr
// [ 1, 2, 3, 4 ] newArr// 扩展运算符(...)
let newArr = [...arr]
newArr.push(4)
console.log(arr, 'arr')
console.log(newArr, 'newArr')
// [ 1, 2, 3 ] arr
// [ 1, 2, 3, 4 ] newArr// concat()方法
let newArr = [].concat(arr)
newArr.push(4)
console.log(arr, 'arr')
console.log(newArr, 'newArr')
// [ 1, 2, 3 ] arr
// [ 1, 2, 3, 4 ] newArr// slice()方法
let arr1 = [1, 2, 3]
let arr2 = at()arr2.push(4)
console.log( arr1, 'arr1' )
console.log( arr2, 'arr2' )
// [ 1, 2, 3 ] arr1
// [ 1, 2, 3, 4 ] arr2// Array.from()方法
let arr1 = [1, 2, 3]
let arr2 = Array.from(arr1)arr2.push(4)
console.log( arr1, 'arr1' )
console.log( arr2, 'arr2' )
// [ 1, 2, 3 ] arr1
// [ 1, 2, 3, 4 ] arr2

当数组变成多层时,以上的方法就不再适用了

let arr = [1, 2, 3, [4, 5]]
let newArr = []
arr.forEach( item => {newArr.push(item)
})
newArr[3].push(6)
console.log(arr, 'arr')
console.log(newArr, 'newArr')
// [ 1, 2, 3, [ 4, 5, 6 ] ] arr
// [ 1, 2, 3, [ 4, 5, 6 ] ] newArr
// 发现结果中,不管原数据和新数据都push进去了新数据

所以还是使用封装的deepClone方法,判断每一项的具体类型,进而实现数据的拷贝

// 深拷贝(多层)
let newArr = deepClone(arr)
newArr.push(4)
console.log(arr, 'arr')
console.log(newArr, 'newArr')
// [ 1, 2, 3 ] arr
// [ 1, 2, 3, 4 ] newArr
// deepClone方法同上

有问题欢迎评论指出,博主会及时改正的🙇‍

本文发布于:2024-01-28 06:12:58,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063935955379.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:深浅
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23