0
点赞
收藏
分享

微信扫一扫

JavaScript复制数据的几种级别-递归实现深拷贝-数组常用的方法


Day_4——JavaScript复制数据的几种级别-递归实现深拷贝-数组常用的方法

  • ​​JavaScript复制数据的几种级别​​
  • ​​1. 赋值​​
  • ​​2. 浅拷贝​​
  • ​​3.深拷贝​​
  • ​​递归实现深拷贝​​
  • ​​数组常用方法​​
  • ​​改变原数组形式​​
  • ​​1. push()​​
  • ​​2. pop()​​
  • ​​3. unshift()​​
  • ​​4. shift()​​
  • ​​5. reverse()​​
  • ​​6. sort()​​
  • ​​7. splice()-注意splice()的实现原理​​
  • ​​不改变原数组形式​​
  • ​​8. slice()​​
  • ​​9. join()​​
  • ​​10. concat()​​
  • ​​11. indexOf()​​
  • ​​12. lastIndexOf()​​
  • ​​总结​​

JavaScript复制数据的几种级别

1. 赋值

  • 把一个变量存储的值复制一份给到另一个变量
  • 基本数据类型赋值以后两个变量没有关系
  • 复杂数据类型赋值以后, 两个变量操作同一个存储空间

var o1 = { name: 'Jack' }
var o2 = o1
console.log(o1)
console.log(o2)
o2.name = 'Rose'
console.log(o1)
console.log(o2)

2. 浅拷贝

  • 制作一个和原始数据一模一样的数据结构
  • 把原始数据结构中的内容一个一个的复制到新数据结构中
  • 只能拷贝一层数据结构

2. 浅拷贝
var o1 = { name: 'Jack', age: 18, gender: '男', info: { weight: 180, height: 180 } }
// 准备一个和 o1 一样的数据结构
var o2 = {}
// 遍历 o1 对象, 把每一个内容逐个添加到 o2 内
for (var k in o1) {
// k 就是 o1 内的每一个 key
// 当 k === 'info' 的时候
// o2['info'] = o1['info']
// 因为这个 info 存储的是一个地址
// 所以此时 o2.info 和 o1.info 存储的是同一个对象的地址
o2[k] = o1[k]
}
console.log(o1, o2)
o2.name = 'Rose'
o2.info.weight = 200
console.log(o1, o2)

3.深拷贝

  • 按照浅拷贝的方式来继续进行第二层数据的拷贝
  • 当我拷贝第一层数据的时候
  • 如果遇到某一个 key 保存的值是复杂数据类型
  • 进入到这个复杂数据类型内再次拷贝

var o1 = {
name: 'Jack',
age: 18,
gender: '男',
info: {
weight: 180,
height: 180,
address: {
city: '北京'
}
},
hobby: {
ball: [ '篮球', '足球', '羽毛球' ],
sport: [ '跑步', '游泳' ]
}
}

var o2 = {}

递归实现深拷贝

问题: 如何判断一个数据结构是 数组还是对象 ?
语法: Object.prototype.toString.call(你要判断的数据)
返回值: 一个字符串类型 '[object 数据类型]'
console.log(Object.prototype.toString.call(123))
console.log(Object.prototype.toString.call(''))
console.log(Object.prototype.toString.call(true))
console.log(Object.prototype.toString.call(undefined))
console.log(Object.prototype.toString.call(null))
console.log(Object.prototype.toString.call({}))
console.log(Object.prototype.toString.call([]))
console.log(Object.prototype.toString.call(function () {}))

递归实现深拷贝

console.log(Object.prototype.toString.call(123));
function deepCopy(origin,target){
// 遍历
for(var i in origin){
// 如果是数组
if(Object.prototype.toString.call(origin[i]) === '[object Array]'){
deepCopy(origin[i],target[i])
}else if(Object.prototype.toString.call(origin[i]) === '[object object]'){
deepCopy(origin[i],target[i])
}else{
target[i] = origin[i]
}
}
}
deepCopy(o1,o2)

数组常用方法

改变原数组形式

1. push()

语法: 数组.push(数据, 数据, ...)
作用: 向数组的末尾追加指定的数据
返回值: 追加数据后最新的数组的长度
var res = arr.push('新来的', '2222222222')
console.log('追加之后 : ', arr)
console.log('返回值 : ', res)

2. pop()

语法: 数组.pop()
作用: 删除数组的最后一个数据
返回值: 被删除的数据
var res = arr.pop()
console.log('删除之后 : ', arr)
console.log('返回值 : ', res)

3. unshift()

语法: 数组.unshift(数据)
作用: 向数组的最前面插入数据
返回值: 插入数据后最新的数组的长度
var res = arr.unshift('新来的')
console.log('插入之后 : ', arr)
console.log('返回值 : ', res)

4. shift()

语法: 数组.shift()
作用: 删除数组最前面一个数据
返回值:

5. reverse()

语法: 数组.reverse()
作用: 反转数组
返回值: 反转以后的数组
var arr = [ 100, 200, 300, 400 ]
console.log('原始数组 : ', arr)
var res = arr.reverse()
console.log('反转之后 : ', arr)
console.log('返回值 : ', res)

6. sort()

语法:
数组.sort()
数组.sort(function (a,) { return a - b }) 升序
数组.sort(function (a,) { return b - a }) 降序
作用: 对数组进行排序
返回值: 排序后的数组
var arr = [ 1, 2, 10, 21, 33, 13, 110, 109, 3, 103 ]
console.log('原始数组 : ', arr)
var res = arr.sort()
var res = arr.sort(function (a,) { return a - b })
var res = arr.sort(function (a,) { return b - a })
console.log('排序之后 : ', arr)
console.log('返回值 : ', res)

7. splice()-注意splice()的实现原理

语法:  注意:影响的是本身的数组内容和长度
数组.splice(开始索引, 多少个)
数组.splice(开始索引, 多少个, 要插入的数据)
注意: 从哪一个索引开始截取, 从哪一个索引插入
作用: 截取数组部分内容, 并插入新的内容
返回值: 一个新的数组
你截取的所有内容放在这个新数组内
var arr = [ 100, 200, 300, 400, 500, 600, 700 ]
// 0 1 2 3 4 5 6
console.log('原始数组 : ', arr)
// 从 [2] 开始, 截取 3 个内容
// var res = arr.splice(2, 3)
// 从 [2] 开始, 截取 1 个内容, 把 '新来的' 插入到 [2] 位置
var res = arr.splice(2, 1, '新来的', '2222')
console.log('截取之后 : ', arr)
console.log('返回值 : ', res)

不改变原数组形式

8. slice()

语法: 数组.slice(开始索引, 结束索引)
注意: 包前不包后, 包含开始索引, 不包含结束索引
注意: 可以填写负整数, 等价于 length + 负整数
作用: 从数组内截取部分数据(不会改变原始数组, 而是复制出来)
返回值: 必然是一个新数组
数组内就是截取出来的部分数据
var arr = [ 100, 200, 300, 400, 500, 600, 700 ]
console.log('原始数组 : ', arr)
[2] 开始截取到 [5], 包含 [2] 数据, 不包含 [5] 数据
var res = arr.slice(2, 5)
var res = arr.slice(2, -2)
console.log('返回值 : ', res)

9. join()

语法: 数组.join('连接符')
作用: 把数组内的每一项用连接符连接成一个字符串
返回值: 连接好的字符串

var arr = [ 2022, 3, 5 ]
console.log('原始数组 : ', arr)
var res = arr.join(' ^_^ ')
console.log('返回值 : ', res)

10. concat()

语法: 数组.concat(数组2, 数据)
作用: 把参数的数组展开拼接到原始数组内
返回值: 拼接好的数组

var arr = [ 10, 20, 30, 40 ]
console.log('原始数组 : ', arr)
var res = arr.concat([ 50, 60 ], 70, [ 80, 90, [ 100, 200 ] ])
console.log('返回值 : ', res)

11. indexOf()

语法:
数组.indexOf(数据)
数组.indexOf(数据, 开始索引)
作用: 从前向后检索数组中第一次出现该数据的索引位置
返回值: 是一个数字
如果检索到的该数据, 那么就是该数据第一次出现的索引位置
如果没有该数据, 那么就是 -1

var arr = [ 100, 200, 300, 100, 200, 100, 400 ]
console.log('原始数组 : ', arr)
// 从 arr 数组中检测 100 这个数据, 会从 [0] 位置开始向后检索
var res = arr.indexOf(100)
//从 arr 数组中检测 100 这个数据, 会从 [1] 位置开始向后检索
var res = arr.indexOf(100, 1)
var res = arr.indexOf(100, 6)
console.log('返回值 : ', res)

12. lastIndexOf()

语法:
数组.lastIndexOf(数据)
数组.lastIndexOf(数据, 开始索引)
作用: 从后向前检索数组中第一次出现该数据的索引位置
返回值: 是一个数字
如果检索到的该数据, 那么就是该数据第一次出现的索引位置
如果没有该数据, 那么就是 -1


var arr = [ 100, 200, 300, 100, 200, 100, 400 ]
console.log('原始数组 : ', arr)
//从 arr 数组中检测 100 这个数据, 会从 最后 位置开始向前检索
var res = arr.lastIndexOf(100)
//从 arr 数组中检测 100 这个数据, 会从 [4] 位置开始向前检索
var res = arr.lastIndexOf(100, 4)
console.log('返回值 : ', res)

总结

1. 对象数据类型
+ 是一个 JS 的复杂数据类型
+ 是一个承载数据的集合
+ 是一个无序的数据集合
+ 是一个键值对的集合

2. 对象数据类型的创建
2-1. 字面量方式创建
=> var obj = { 键值对, 键值对 }
2-2. 内置构造函数方式创建
=> var obj = new Object()

3. 对象的操作语法
3-1. 点语法
=> : 对象.键名 =
=> : delete 对象.键名
=> : 对象.键名 =
=> : 对象.键名
3-2. 数组关联语法
=> : 对象['键名'] =
=> : delete 对象['键名']
=> : 对象['键名'] =
=> : 对象['键名']

4. 对象的遍历
+ 利用 for in 循环遍历对象
+ 示例:
for (var k in 对象) {
// 随着循环, k 就是对象内的每一个键名
// 随着循环, 对象[k] 就是对象内每一个值
}

5. 数组数据类型
+ JS 中的一个复杂数据类型
+ 是一个有序的数据集合, 按照索引排列数据
+ 索引: 0 开始, 依次 +1

6. 数组的创建
6-1. 字面量方式
=> var arr = []
=> var arr = [ 数据1, 数据2, ... ]
6-2. 内置构造函数方式
=> var arr = new Array()
=> var arr = new Array( 数据1, 数据2, ... )
=> var arr = new Array( 数字 )

7. 数组的基本操作
7-1. length 属性
+ 是一个读写的属性
+ : 获取
=> 语法: 数组.length
=> 得到: 该数组的长度
+ : 设置
=> 语法: 数组.length = 数字
=> 结果:
-> 你设置的数字 小于 length, 从后面开始删除
-> 你设置的数字 等于 length, 不变
-> 你设置的数字 大于 length, 多出来的位置使用 empty 补齐
7-2. 索引 属性
+ 是一个读写的属性
+ : 获取
=> 语法: 数组[索引]
=> 得到:
-> 如果该数组有该索引位置, 那么就是该索引位置的数据
-> 如果该数组没有该索引位置, 那么就是 undefined
+ : 设置
=> 语法: 数组[索引] =
=> 结果:
-> 你设置的索引 小于 length, 修改指定索引位置的数据
-> 你设置的索引 等于 length, 追加一个数据
-> 你设置的索引 大于 length, 中间空余位置使用 empty 补齐
7-3. 遍历 数组
+ 使用循环遍历数组
+ 示例
for (var i = 0; i < arr.length; i++) {
// 随着循环, i 就是每一个索引
// 随着循环, arr[i] 就是每一个数据
}

8. 数组常用方法
+ push() 后面追加
+ pop() 后面删除
+ unshift() 前面添加
+ shift() 前面删除
+ reverse() 反转数组
+ sort() 排序数组
+ splice() 截取数组并插入
+ 以上方法会直接修改原始数组
+ slice() 截取数组
+ concat() 拼接数组
+ join() 把数组内内容连接成字符串
+ indexOf() 查询数据所在索引位置
+ lastIndexOf() 从后向前查询数据所在索引位置

9. 排序算法
9-1. 选择排序
for (var i = 0; i < arr.length - 1; i++) {
var minIndex = i
for (var j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) minIndex = j
}
if (minIndex !== i) {
var tmp = arr[i]
arr[i] = arr[minIndex]
arr[minIndex] = tmp
}
}

9-2. 冒泡排序
for (var i = 0; i < arr.length - 1; i++) {
var flag = false
for (var j = 0; j < arr.length - 1- i; j++) {
if (arr[j] > arr[j + 1]) {
var tmp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = tmp
flag = true
}
}
if (!flag) break
}

9-3. 计数排序
var tmp = []
for (var i = 0; i < arr.length; i++) {
var item = arr[i]
tmp[item] ? tmp[item]++ : tmp[item] = 1
}
arr.length = 0
for (var i = 0; i < tmp.length; i++) {
if (!tmp[i]) continue
var count = tmp[i]
for (var j = 0; j < count; j++) {
tmp.push(i)
}
}

9-4. 快速排序(二分法)
function quickSort(arr) {
if (arr.length <= 1) return arr

var center = arr.splice(parseInt(arr.length / 2), 1)[0]
var left = [], right = []
for (var i = 0; i < arr.length; i++) {
arr[i] < center ? left.push(arr[i]) : right.push(arr[i])
}

return [ ...quickSort(left), center, ...quickSort(right) ]
}

9-5. 插入排序
for (var i = 1; i < arr.length; i++) {
var tmp = arr[i]

var j = i - 1
while (j >= 0 && tmp > arr[j]) {
arr[j + 1] = arr[j]
j--
}

arr[j + 1] = tmp
}


举报

相关推荐

0 条评论