Javascript中数组的合并和对象的合并、拷贝

1.数组合并

我们在项目过程中,有时候会遇到需要将两个数组合并成为一个的情况。比如:

const a = [1, 2, 3]
const b = [4, 5, 6]

有两个数组a、b,需求是将两个数组合并成一个。方法如下:

1.1 concat

concat方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。

  const c = a.concat(b)
  console.log(c)  // [ 1, 2, 3, 4, 5, 6 ]
  console.log(a)  // [ 1, 2, 3 ]  不改变本身

contact示例:

['hello'].concat(['world'])
// ["hello", "world"]

['hello'].concat(['world'], ['!'])
// ["hello", "world", "!"]

[].concat({a: 1}, {b: 2})
// [{ a: 1 }, { b: 2 }]

[2].concat({a: 1})
// [2, {a: 1}]

如果数组成员包括对象,concat方法返回当前数组的一个浅拷贝。所谓“浅拷贝”,指的是新数组拷贝的是对象的引用。

var obj = { a: 1 };
var oldArray = [obj];

var newArray = oldArray.concat();

obj.a = 2;
newArray[0].a // 2
1.2 for循环

遍历其中一个数组,把该数组中的所有元素依次添加到另外一个数组中。

  for (var i in b) {
    a.push(b[i])
  }

这样的写法可以解决第一种方案中对内存的浪费,但是会有另一个问题:丑!

1.3 apply或…扩展运算符

push方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,push方法会改变原数组

  • apply

函数的apply方法有一个特性,那就是func.apply(obj,argv),argv是一个数组。所以我们可以利用这点,直接上代码:

a.push.apply(a,b);

调用a.push这个函数实例的apply方法,同时把,b当作参数传入,这样a.push这个方法就会遍历b数组的所有元素,达到合并的效果。
这里可能有点绕,我们可以把b看成[4,5,6],变成这样:

 a.push.apply(a,[4,5,6]);

然后上面的操作就等同于:

a.push(4,5,6);
  • …扩展运算符

扩展运算符用三个点号(…)表示,功能是把数组或类数组对象展开成一系列用逗号隔开的值。
特殊应用场景:

//数组深拷贝
var arr2 = arr;
var arr3 = [...arr];
console.log(arr === arr2); //true, 说明arr和arr2指向同一个数组
console.log(arr === arr3); //false, 说明arr3和arr指向不同数组

//把一个数组插入另一个数组字面量
var arr4 = [...arr, 4, 5, 6];
console.log(arr4);//[1, 2, 3, 4, 5, 6]

//字符串转数组
var str = 'love';
var arr5 = [...str];
console.log(arr5);//[ 'l', 'o', 'v', 'e' ]

本题解:

a.push(...b)
2.对象合并
2.1 $.extend()(jquery方法)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>对象合并</title>
  <script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<script>
  const obj1 = {a: 1}
  const obj2 = {b: 1}
  const c = $.extend(obj1, obj2)
  console.log(c)     // {a: 1, b: 1}
  console.log(obj1) // {a: 1, b: 1}  obj1已被修改
</script>
</body>
</html>

或者

const obj3 = $.extend({}, obj1, obj2)
console.log(obj3)   //{a: 1, b: 1} 不会改变obj1,obj2
2.2 遍历赋值
const obj1 = {a: 1}
  const obj2 = {b: 1}
  for (var key in obj2) {
    if (obj2.hasOwnProperty(key) === true) {
      //此处hasOwnProperty是判断自有属性,使用 for in 循环遍历对象的属性时,
      // 原型链上的所有属性都将被访问会避免原型对象扩展带来的干扰
      obj1[key] = obj2[key]
    }
  }
  console.log(obj1)         //{'a':1,'b':2,'c':3};
2.3 Object.assign()

可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

Object.assign(target, ...sources)

复制一个对象

const obj = {a: 1, b: 2}
const copyObj = Object.assign({}, obj)
console.log(copyObj) // { a: 1,b:2 }

合并多个对象

const obj1 = {a: 1}
const obj2 = {b: 2}
const obj3 = {c: 3}
var obj = Object.assign(obj1, obj2, obj3)
console.log(obj) // { a: 1, b: 2, c: 3 }
console.log(obj1)  // { a: 1, b: 2, c: 3 }, 且目标对象自身也会改变。
2.4 对象的深拷贝和浅拷贝对象的深浅克隆
2.4.1 浅拷贝
  const obj1 = {a: 1}
  const obj2 = {b: {b1: 22, b2: 33}}

  Object.assign(obj1, obj2)   //obj1拷贝了obj2的属性

  console.log(obj1)       // {'a':1,'b'{'b1':22,'b2':33}}
  console.log(obj1.b.b1)  // 22

  obj2.b.b1 = 44          //obj2重新赋值
  console.log(obj1.b.b1)  // 44  obj1.b仅拷贝了对象的指引,所以受原obj2的影响
2.4.2 深拷贝

(1)

const obj1 = {a: 1}
  const obj2 = {b: {b1: 22, b2: 33}}

  $.extend(true, obj1, obj2)   //第一个参数设为true表示深复制

  console.log(obj1)       // {'a':1,'b'{'b1':22,'b2':33}}
  console.log(obj1.b.b1)  // 22

  obj2.b.b1 = 44          //obj2重新赋值
  console.log(obj1.b.b1)  // 44  obj1拷贝了obj2的所有属性以及值,并不受obj2的影响

(2)JSON.pase()和JSON.stringfy()结合实现深拷贝

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值