前言
一些没怎么用过的数组方法与深浅拷贝 ( 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
原始数据的分配在执行时会直接在栈空间中进行分配
jsvar name = "star"
复杂数据类型的分配会在堆内存中开辟一块空间,栈中存储的地址是指向堆中的这块空间的指针返回变量值
jsvar 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()
方法读取 this
的 length
属性,然后访问每个整数索引 ,直到到达末尾或 callbackFn
返回 true
。
Array.prototype.every()
测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值。
与 Array.prototype.some() 极其相似