[jquery] jQuery 实现深浅拷贝 $.extend( )

jQuery 实现深浅拷贝 :

1. js实现 深浅拷贝

  • 在复制一个数据类型的时候(特指复杂数据类型, 数组或者对象)

  • 在 JS 内, 对于 “复制” 有三个级别 :

    1. 赋值

    2. 浅拷贝

    3. 深拷贝

1.1 赋值 :
  • 简单的地址复制

  • 使用 赋值符号( = ) 进行的操作

  • 对于基本数据类型, 赋值之后两个变量之间没有任何关系

  • 对于复杂数据类型, 赋值之后两个变量操作同一个数据存储空间

obj存的是地址

// 1. 赋值
let n1 = 5
// 把 n1 的值赋值给了 n2
let n2 = n1
console.log(n1, n2)    // 5  5
n2 = 10
console.log(n1, n2)    // 5  10

const o1 = { name: 'Jack' }

// 进行赋值操作, 把 o1 的值赋值给了 o2
// 因为 o1 这个变量内存储的是指向一个 对象数据类型 的空间地址
// 赋值的过程中, 就是把 o1 存储的地址赋值给了 o2
// 所以给到 o2 的依旧是一个 地址
// 从此以后 o1 和 o2 操作一个对象存储空间
const o2 = o1
console.log(o1, o2)

// 使用任意一个变量名修改对象空间内的成员
o2.name = 'Rose'
console.log(o1, o2)

在这里插入图片描述

在这里插入图片描述

1.2 浅拷贝 :

=> 创建一个和原先数据结构一模一样的数据结构

  • 假如原先是个数组数据类型, 那么就新创建一个数组

  • 假如原先是个对象数据类型, 那么就新创建一个对象

=> 通过 for in 循环去遍历原先数据结构

  • 把里面的每一个数据分别在新的数据结构中复制一份

  • 对于一维数据结构有效

  • 如果是多维数据结构,没有意义 , 那么从第二维度开始, 依旧是操作同一个存储空间

// 2. 浅拷贝
const o1 = { name: 'Jack', age: 18, info: { height: 180 } }

// 2-1. 创建一个和原先数据结构一模一样的结构
const o2 = {}

// 2-2. 循环遍历原始数据结构
for (const key in o1) {
  // 2-3. 分别在新的数据结构中进行赋值
  // 在进行 for in 遍历的时候
  // 在这里, 当 key === info 的时候
  // o1[key] 存储的也是一个地址
  // o2[key] 就是把 o1[key] 存储的地址复制了一份过去
  // 从此以后, o1 和 o2 虽然是两个数据空间
  // 但是 o1.info 和 o2.info 操作的是一个数据空间
  // o2.info = o1.info
  // 因为 info 内存储的是一个 地址
  // 赋值以后, o2.info 和 o1.info 存储的是同一个地址
  o2[key] = o1[key]
}

// 此时 o1 和 o2 不是一个对象存储空间
// 只是长得一模一样的两个对象存储空间
// 用任意一个区操作的时候, 另外一个不会改变
console.log(o1, o2)

在这里插入图片描述

// 修改
o2.name = 'Rose'
o2.age = 20
console.log(o1, o2)

在这里插入图片描述

// 修改第二维度 info 内的数据
o2.info.height = 200
console.log(o1, o2)

在这里插入图片描述
知识点扩展 :

// 准确的判断所有数据类型
// 语法: Object.prototype.toString.call(你要判断的数据类型)
// 返回值: 该数据类型的 类型字符串 '[object 类型]'
console.log(Object.prototype.toString.call({}))       //     Object
console.log(Object.prototype.toString.call([]))       //     Array
console.log(Object.prototype.toString.call(123))      //     Number
console.log(Object.prototype.toString.call('123'))    //     String
console.log(Object.prototype.toString.call(true))     //     Boolean
console.log(Object.prototype.toString.call(null))     //     Null
console.log(Object.prototype.toString.call(undefined))//     Undefined
console.log(Object.prototype.toString.call(/^$/))     //     RegExp
console.log(Object.prototype.toString.call(new Date()))//    Date
console.log(Object.prototype.toString.call(function () {}))//Function

在这里插入图片描述

1.3 深拷贝 :

=> 不停地重复浅拷贝的工作

=> 复制出一份完全一模一样的数据结构

=> 不管多少维度的数据结构, 都能完整独立的复制过来

=> 实现方式:

  • 使用 递归 的方式进行逐层数据结构的 遍历数据并赋值

  • 当我循环遍历的时候, 如果碰到的还是复杂数据类型

  • 那么就递归进行遍历

// 3. 深拷贝
const o1 = {
  name: 'Jack',
  age: 18,
  info: {
    weight: 180,
    height: 180,
    desc: {
      msg: '这个人很懒, 什么都没有留下!'
    }
  },
  hobby: ['吃饭', '睡觉', ['篮球', '足球']]
}
const o2 = {}
// 3-1. 书写函数来完成(递归函数)
// 使用递归的方式进行深拷贝
function deepCopy(o2, o1) {
  // 做: 把 o1 内的所有数据全部拷贝到 o2 内部
  // console.log(o1, o2)
  //3-2. 直接循环遍历 o1 数据
  for (let key in o1) {
    // console.log(key);
    // 判断, 如果是 对象数据类型 或者 数组数据类型, 不进行赋值
    // 否则, 才进行赋值
    // 如果 o1[key] 是一个对象数据类型
    // o2[key] 也要创建为一个对象数据类型
    // 如果 o1[key] 是一个数组数据类型
    // o2[key] 也要创建为一个数组数据类型
    // 如果 o1[key] 是一个基本数据类型
    // o2[key] 直接赋值
    if (Object.prototype.toString.call(o1[key]) === '[object Object]') {
      // 是对象
      // console.log('o1[key] 是一个对象数据类型 : ', key)
      o2[key] = {}
      // 在这个位置, o1[key] 是一个对象数据类型
      // o2[key] 也是一个数据类型
      // o1[key] 里面的每一个数据复制一份到 o2[key]
      deepCopy(o2[key], o1[key])
    } else if (o1[key].constructor === Array) {
      // 是数组
      // console.log('o1[key] 是一个数组数据类型 : ', key)
      o2[key] = []
      // 把 o1[key] 内部的所有数据放在 o2[key] 内
      deepCopy(o2[key], o1[key])
    } else {
      // console.log('o1[key] 是一个基本数据类型 : ', key)
      // 直接复制
      o2[key] = o1[key]
    }
  }
}
// 将来使用的时候
deepCopy(o2, o1)
console.log(o1, o2)
// 修改数据
o2.info.desc.msg = 'hello world'

在这里插入图片描述

1.4 深拷贝 - 方案2
  • 只能是在 对象 和 数组 数据结构中使用

  • 不能有函数

  • 利用 json 格式字符串

4-1. 把源数据转换成 json 格式字符串

4-2. 把 json 格式字符串转换回 js 数据类型

// 4. 深拷贝 - 方案2
const o1 = { name: 'Jack', age: 18, info: { weight: 180, height: 180, desc: { msg: '你好 世界' } }, hobby: [ '吃饭', '睡觉' ] }
console.log(o1)

// 把 o1 转换成 json 格式字符串
// 现在的 jsonStr 就是基本数据类型
const jsonStr = JSON.stringify(o1)
console.log(jsonStr)

// 把 s 转换成一个 JS 的对象格式
const o2 = JSON.parse(jsonStr)
console.log(o2)

// 修改
o2.info.desc.msg = 'hello world'
console.log(o1, o2)

2. jQuery 实现深浅拷贝的方法 $.extend( ):

const o1 = {
  name: 'Jack',
  age: 18,
  info: {
    weight: 180,
    height: 180,
    desc: {
      msg: '这个人很懒, 什么都没有留下!',
      title: '你好 世界'
    }
  },
  hobby: [ '吃饭', '睡觉', [ '篮球', '羽毛球', '足球' ] ]
}
2.1 浅拷贝 :

=> 语法: $.extend(对象1, 对象2, 对象3, …)
=> 作用: 把从 对象2 开始的所有对象内的数据进行浅拷贝到 对象1 内
=> 实现的是浅拷贝

// 1. 实现浅拷贝
// 把 o1 内的所有数据进行浅拷贝到 o2 身上
let o2 = {}
$.extend(o2, o1)
console.log(o1, o2)
// 修改一下数据
o2.name = 'Rose'
// 第二维度修改
o2.info.height = 200
console.log(o1, o2)

在这里插入图片描述

2.2 深拷贝:

=> 语法: $.extend(true, 对象1, 对象2, 对象3, …)
=> 作用: 把从 对象2 开始的所有对象内的数据进行深拷贝到 对象1 内
=> 实现的是深拷贝

// 2. 实现深拷贝
let o2 = {}
$.extend(true, o2, o1)
// console.log(o1, o2)
// 修改
o2.name = 'Tom'
o2.info.height = 250
o2.info.desc.msg = '这个人更懒'
console.log(o1, o2)

在这里插入图片描述
在这里插入图片描述

赋值,改一个,另一个也跟着变
浅拷贝,一维改一个,另一个独立的,不变
深拷贝,两个完全独立,随便改,无所谓







参考: [前端 _ jQuery 之 小白版 ( 下 )](https://blog.csdn.net/weixin_58099903/article/details/119272571)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值