js - 复制一个数组

63 阅读1分钟

《用得上的前端知识》系列 - 你我都很忙,能用100字说清楚,绝不写万字长文

1、扩展运算符(浅层拷贝)

自从ES6出现以来,这已经成为最流行的方法。这个方法不能有效的拷贝多维数组。

// 浅层拷贝
let ary = [[1], 2, 3]
let ary2 = [...ary]

ary2[0].push(4)
ary2.push(5)
console.log(ary, ary2) //[[1,4],2,3] [[1,4],2,3,5]

2、循环拷贝(如:for循环、for in循环、while循环等)

// 浅层拷贝
let ary= [1, 2, 3]
let ary2 = []

for (let i = 0; i< ary.length; i++) {
  ary2[i] = ary[i]
}
console.log(ary, ary2) //[1,2,3] [1,2,3]

3、Array.filter(浅层拷贝)

let ary = [[1], 2, 3]
let ary2 = ary.filter(() => true)

ary2[0].push(4)
ary2.push(5)

console.log(ary, ary2) //[[1,4],2,3] [[1,4],2,3,5]

4、Array.slice(浅层拷贝)

let ary = [[1],2,3]
let ary2 = ary.slice(0)

ary2[0].push(4)
ary2.push(5)

console.log(ary, ary2): //[[1,4],2,3] [[1,4],2,3,5]

5、Array.concat(浅层拷贝)

let ary = [[1],2,3]
let ary2 = [].concat(ary)

ary2[0].push(4)
ary2.push(5)

console.log(ary, ary2): //[[1,4],2,3] [[1,4],2,3,5]

6、Array.from(浅层拷贝)

ES6的Array.from 方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。

let ary = [[1],2,3]
let ary2 = Array.from(ary)

ary2[0].push(4)
ary2.push(5)

console.log(ary, ary2) //[[1,4],2,3] [[1,4],2,3,5]

7、map(浅层拷贝)

let ary = [[1],2,3]
let ary2 = ary.map(val => val)

ary2[0].push(4)
ary2.push(5)

console.log(ary, ary2) //[[1,4],2,3] [[1,4],2,3,5]

8、JSON.parse & JSON.stringify(深层拷贝)

let ary = [[1],2,3]
let ary2 = JSON.parse( JSON.stringify(ary) )

ary2[0].push(4)
ary2.push(5)

console.log(ary, ary2) //[[1,4],2,3] [[1,4],2,3,5]

简易版深层拷贝(不考虑循环引用)

let ary = [[1], 2, 3]
let ary2

function copy (obj) {
  let newobj = obj.constructor === Array ? [] : {}
  
  if(typeof obj !== 'object') {
    return
  }
  
  // for in循环也可以用来遍历数组
  for (let i in obj) {
    newobj[i] = typeof obj[i] === 'object' ? copy(obj[i]) : obj[i]
  }
  
  return newobj
}

ary2 = copy(ary)
ary2[0].push(4)
ary2.push (5)

console.log(ary, ary2) //[[1],2,3] [[1,4],2,3,5]