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 深拷貝
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的影響