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

前言

一些没怎么用过的数组方法与深浅拷贝 ( 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() 极其相似

相关推荐
前端李易安33 分钟前
Web常见的攻击方式及防御方法
前端
PythonFun1 小时前
Python技巧:如何避免数据输入类型错误
前端·python
hakesashou1 小时前
python交互式命令时如何清除
java·前端·python
天涯学馆1 小时前
Next.js与NextAuth:身份验证实践
前端·javascript·next.js
HEX9CF1 小时前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
ConardLi1 小时前
Chrome:新的滚动捕捉事件助你实现更丝滑的动画效果!
前端·javascript·浏览器
ConardLi2 小时前
安全赋值运算符,新的 JavaScript 提案让你告别 trycatch !
前端·javascript
凌云行者2 小时前
使用rust写一个Web服务器——单线程版本
服务器·前端·rust
华农第一蒟蒻2 小时前
Java中JWT(JSON Web Token)的运用
java·前端·spring boot·json·token
积水成江2 小时前
关于Generator,async 和 await的介绍
前端·javascript·vue.js