数组
数组深拷贝和浅拷贝
浅拷贝
Object.assign([拷贝参数]):- 递归实现
扩展运算符:
const demo = {
name: 'Tom',
age: 18,
family: [
{name: 'mama'},
{name: 'baba'}
]
}
// 第一层是深拷贝,修改demo2不会影响demo,但是修改family的值会影响demo
const demo2 = {...demo}
slice()(仅适用于数组):
slice() : 返回一个新数组,这一对象是一个由 start 和 end 决定的原数组的浅拷贝, 左开右闭(
[start,end))
// 基本数据类型,slice实现基本数据类型深拷贝,修改arr1不会影响arr
const arr = [1,2,3,4]
const arr1 = arr.slice()
// 数组元素非基本数据类型,是浅拷贝,修改arr3会影响arr2
const arr2 = [{name: 'Tom'},{name: 'Marry'}]
const arr3 = arr2.slice()
concat():
concat : 用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组
// 基本数据类型,concat实现基本数据类型深拷贝,修改arr1不会影响arr
const arr = [1,2,3,4]
const arr1 = arr.concat()
// 数组元素非基本数据类型,是浅拷贝,修改arr3会影响arr2
const arr2 = [{name: 'Tom'},{name: 'Marry'}]
const arr3 = arr2.concat()
深拷贝
- 使用
JSON:- 步骤:
JSON.stringify()将对象或数组转为JSON字符串;JSON.parse()将JSON字符串解析为Object类型。 - 限制:
- 它不能正确处理包含循环引用的对象。
- 它不能正确复制特殊对象,如Date、RegExp和函数。
- 它会丢失原始对象的原型链信息。
- 步骤:
Lodash的_.cloneDeep方法- 递归函数实现:
hasOwnProperty(): 返回一个布尔值,表示对象自有属性(而不是继承来的属性)中是否具有指定的属性
const demo = {
name: 'Tom',
age: 18,
family: [
{name: 'mama'},
{name: 'baba'}
]
}
function deepClone(obj) {
// 判断是否是对象
if (typeof obj !== 'object') return
// 判断是数组还是对象
let newObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
// 判断是否有该属性
if (obj.hasOwnProperty(key)) {
newObj[key] =
typeof obj[key] === 'object'
?
deepClone(obj[key])
:
obj[key]
}
}
return newObj
}
const demo1 = deepClone(demo)
如何判断一个数组
在 JavaScript 中,要判断一个变量是否是数组,你可以使用以下几种方法:
-
使用
Array.isArray()方法:if (Array.isArray(variable)) { // 变量是一个数组 } else { // 变量不是一个数组 }这是最常用的方法,因为它是 JavaScript 内置的,能够准确地检测一个值是否是数组。
-
使用
instanceof操作符:if (variable instanceof Array) { // 变量是一个数组 } else { // 变量不是一个数组 }这种方法也可以用来检测一个对象是否是数组,但需要注意,如果变量是在不同的 JavaScript 上下文(比如不同的窗口或帧)中创建的,
instanceof可能会产生错误的结果。 -
使用
Object.prototype.toString.call()方法:if (Object.prototype.toString.call(variable) === '[object Array]') { // 变量是一个数组 } else { // 变量不是一个数组 }这种方法是比较底层的方式,通过检查变量的内部
[[Class]]属性来确定其类型。虽然不太常用,但也是一种可靠的方法。
一般来说,推荐使用Array.isArray()方法,因为它更简单、清晰,而且能够准确地检测变量是否是数组。