<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>js數組以及對象合併</title>
<link rel="stylesheet" href="">
<script src="jquery.min.js"></script>
</head>
<body>
<script>
<!-- 1 concat() -->
var arr1 = [1,2,3,4]
var arr2 = [5,6,7,8]
var arr3 = arr1.concat(arr2);
console.log(arr1)
console.log(arr2)
console.log(arr3)
// 總結 concat 鏈接不會使得原數組變化,返回一個新的數組
// 2. 循環遍曆數組
for(var i=0;i<arr2.length;i++){
arr1.push(arr2[i]);
}
// 這種方式改變了 arr1 數組,arr2 沒有變化
// 3. apply() 方法 Array.prototype.push.apply(arr1,arr2) 或者 arr1.push.apply(arr1,arr2)
Array.prototype.push(arr1,arr2)
// 返回值是合併後數組的長度
console.log(arr1,arr2)
arr1.push.apply(arr1,arr2)
console.log(arr1,arr2)
// arr1 數組變化了, arr2沒有變化
// 共享一下測試concat()Array.prototype.push.apply(a,b) 的代碼,有需要的拿走玩玩
// function testClass(){
// var testArray1=[];
// var testArray2=[];
// this.resetArray=function(){
// for(var i=0; i<10000000;i++){
// testArray1.push(i);
// testArray2.push(i+10000000);
// }
// }
// this.applyTest=function(){
// var startTime=0,
// endTime=0;
// console.log(開始合併的時間是:+ (startTime=new Date().getTime()));
// var aa=Array.prototype.push.apply(testArray1,testArray2);
// console.log(aa);
// console.log(合併完成的時間是:+ (endTime=new Date().getTime()));
// console.log(合併數組所用的時間是:+(endTime-startTime));
// }
// this.concatTest=function(){
// var startTime=0,
// endTime=0;
// console.log(開始合併的時間是:+ (startTime=new Date().getTime()));
// var aa= testArray1.concat(testArray2);
// console.log(aa.length);
// console.log(合併完成的時間是:+ (endTime=new Date().getTime()));
// console.log(合併數組所用的時間是:+(endTime-startTime));
// }
// }

// var apply=new testClass();
// apply.resetArray();
// apply.applyTest();

// var concat=new testClass();
// concat.resetArray();
// concat.concatTest();
// 2.對象合併
/**
2.1JQueryextend()方法

**方法定義**jQuery.extend([deep], target, object1, [objectN])

> 用一個或多個其他對象來擴展一個對象,返回被擴展的對象。

   > 如果不指定target,則給jQuery命名空間本身進行擴展。這有助於插件作者為jQuery增加新方法。 如果第一個參數設置為true,則jQuery返回一個深層次的副本,遞歸地複製找到的任何對象(遞歸合併)。否則的話,副本會與原對象共享結構。 未定義的屬性將不會被複制,然而從對象的原型繼承的屬性將會被複制。
*/
var o1={a:1};
var o2={b:2,c:3};
var o3 = $.extend(o1,o2);
console.log(o3);//{a:1,b:2,c:3}
console.log(o1);//{a:1,b:2,c:3}//o1,o2被修改
var o4 = $.extend({},o1,o2)
console.log(o4);//{a:1,b:2,c:3}
console.log(o1);//{a:1}//不會改變o1,o2

/**
2.2Object.assign()方法

方法介紹:可以把任意多個的源對象自身的可枚舉屬性拷貝給目標對象,然後返回目標對象。

Object.assign(target,...sources)

2.2.1複製一個對象
*/
var obj={a:1,b:2};
var copyObj = Object.assign({},obj);
console.log(copyObj);//{a:1,b:2}

// 2.2.2合併多個對象
var o1 ={a:1};
var o2={b:2};
var o3={c:3};
var obj = Object.assign(o1,o2,o3);
console.log(obj)//{a:1,b:2,c:3}
console.log(o1)//{a:1,b:2,c:3},目標對象自身也會改變

/**
2.3遍歷賦值法

代碼邏輯:1.循環對象n中的每一個對應屬性

2.確認對象n中存在該屬性

3.確認對象o中不存在該屬性

*/
var extend=function(o,p){
for(var p in n){
if(n.hasOwnProperty(p) &&(!o.hasOwnProperty(p)))
o[p]=n[p];
}
};
var obj1={a:1};
var obj2={b:2,c:3};
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.4對象的深拷貝和淺拷貝

2.4.1淺拷貝
*/
var o1={a:1};
var o2={b:{b1:11,b2:111}};

$.extend(o1, o2); //o1拷貝了o2的屬性

console.log(o1) // {a:1,b{b1:11,b2:111}}
console.log(o1.b.b1) // 11

o2.b.b1=999; //o2重新賦值
console.log(o1.b.b1) // 999 o1.b僅拷貝了對象的指引,所以受原o2的影響
//
// 2.4.2深拷貝
var o1={a:1};
var o2={b:{b1:11,b2:111}};

$.extend(true,o1, o2); //true 表示深複製

console.log(o1) // {a:1,b{b1:11,b2:111}}
console.log(o1.b.b1) // 11

o2.b.b1=999; //o2重新賦值
console.log(o1.b.b1) //11 o1拷貝了o2的所有屬性以及值,並不受o2的影響
</script>
</body>
</html>

推薦閱讀:

相关文章