一些数组的方法与深浅拷贝

前言

一些没怎么用过的数组方法与深浅拷贝 ( From 04 - Array Cardio Day 1 & 07 - Array Cardio Day 2)

正文

什么是深浅拷贝

深拷贝

对象的深拷贝是指其属性与其拷贝的源对象的属性不共享相同的引用(指向相同的底层值)的副本。因此,当你更改源或副本时,可以确保不会导致其他对象也发生更改;也就是说,你不会无意中对源或副本造成意料之外的更改。

浅拷贝

对象的浅拷贝 是其属性与拷贝源对象的属性共享相同引用(指向相同的底层值)的副本。因此,当你更改源或副本时,也可能导致其他对象也发生更改------也就是说,你可能会无意中对源或副本造成意料之外的更改。
使用方面来说就是一个复制了改动会相互影响,一个不会呗 但是你又说,如果一个对象里套了一个对象,深拷贝后修改子对象的属性值会影响吗?(这可跟熟知的C语言不一样哇,C里面可没有原生的哈希表)
不知道哇,导员没教

Try 一下

直接赋值
浅拷贝

会影响子对象属性

深拷贝
  • 如果一个 JavaScript 对象可以被序列化,即 Object 和 Array ,则存在一种创建深拷贝的方式:使用 [JSON.stringify()]将该对象转换为 JSON 字符串,然后使用 [JSON.parse()]将该字符串转换回(全新的)JavaScript 对象
  • 对于可序列化的对象,也可以使用 structuredClone() 方法。structuredClone() 的不同是允许源代码中的可转移对象转移 到新的副本。但是structuredClone() 不是 JavaScript 语言本身的特性------相反,它是浏览器和任何其他实现了 [window] 这样全局对象的 JavaScript 运行时的一个特性。

    查阅文档发现[可转移对象通常用于共享资源],web worker 这方面了解不多,改日补充

  • 如果一个对象无法被序列化,例如 Function 等,或者该对象中含有诸如 undefined、NaN、Date对象 等,则可以参考一些已经封装好的库(因为笔者日常开发是 React ,因此不可避免的用 immer 封装过 zustand ),可以看看 immer.js

JS 内存管理

内存分配

原始类型:

  • Boolean
  • Number
  • String
  • Null
  • Undefined
  • Symbol(ES6新增)

复杂数据类型:

  • Object

原始数据的分配在执行时会直接在栈空间中进行分配

js 复制代码
var name = "star"

复杂数据类型的分配会在堆内存中开辟一块空间,栈中存储的地址是指向堆中的这块空间的指针返回变量值

js 复制代码
var obj={name:"star",age:18}

垃圾回收机制 - 引用计数

当一个对象有引用指向它时,那么这个对象的引用+1

当一个对象的引用为0时,这个对象就i会被销毁掉

弊端

会产生循环引用

js 复制代码
var obj1 = { info:"1111" }
var obj2 = { info:"2222" }
obj1.info = obj2
obj2.info = obj1

这种每个obj的引用数即为2

当执行以下操作后
obj1 = null
obj2 = null
这时两者互相引用,则其永远不会销毁

这时需要手动去销毁:
obj1.info = null

数组方法

Array.prototype.sort()

简单升降序排序,括号内为 compareFn , 若相同元素则按照原来顺序进行排列

js 复制代码
function compareFn(a, b) {
  if (根据排序标准,a 小于 b) {
    return -1;
  }
  if (根据排序标准,a 大于 b) {
    return 1;
  }
  // a 一定等于 b
  return 0;
}

Array.prototype.reduce()

scss 复制代码
reduce(callbackFn, initialValue)
callbackFn(accumulator,currentValue,currentIndex,array)

若指定 initialValue,则 accumulator 的值和其一样且 currentValue 为 array[0] 的值,currentIndex 为0

不传默认 accumulator 为 array[0] 的值且 currentValue 为 array[1] 的值,currentIndex 为1

array 为数组本身

总结:如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被用作初始值,迭代器将从第二个元素开始执行(即从索引为 1 而不是 0 的位置开始)。

可以看看 Array.prototype.reduce(),示例挺多还不错

Array.prototype.some()

测试数组中是否至少有一个元素通过了由提供的函数实现的测试。找到则返回 true;否则返回 false。它不会修改数组。

若用于非数组对象,some() 方法读取 thislength 属性,然后访问每个整数索引 ,直到到达末尾或 callbackFn 返回 true

Array.prototype.every()

测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值。

与 Array.prototype.some() 极其相似

相关推荐
江号软件分享10 分钟前
有效保障隐私,如何安全地擦除电脑上的敏感数据
前端
web守墓人1 小时前
【前端】ikun-markdown: 纯js实现markdown到富文本html的转换库
前端·javascript·html
Savior`L1 小时前
CSS知识复习5
前端·css
许白掰1 小时前
Linux入门篇学习——Linux 工具之 make 工具和 makefile 文件
linux·运维·服务器·前端·学习·编辑器
中微子6 小时前
🔥 React Context 面试必考!从源码到实战的完整攻略 | 99%的人都不知道的性能陷阱
前端·react.js
中微子7 小时前
React 状态管理 源码深度解析
前端·react.js
加减法原则8 小时前
Vue3 组合式函数:让你的代码复用如丝般顺滑
前端·vue.js
yanlele8 小时前
我用爬虫抓取了 25 年 6 月掘金热门面试文章
前端·javascript·面试
lichenyang4538 小时前
React移动端开发项目优化
前端·react.js·前端框架
你的人类朋友8 小时前
🍃Kubernetes(k8s)核心概念一览
前端·后端·自动化运维