最近在復(fù)習(xí),發(fā)現(xiàn)前端好多知識(shí)點(diǎn)牽一發(fā)動(dòng)全身。
比如我想看一下JQuery的extend源碼,就不得不再好好看看深克隆淺克隆的問題。 ??????
什么是深克???
我們都知道,JavaScript有六種基本的數(shù)據(jù)類型。
五種基本的數(shù)據(jù)類型:string,number,undefined,boolean,null
(在內(nèi)存中表現(xiàn)為一個(gè)值,保存在棧中)
一種復(fù)雜的數(shù)據(jù)類型(引用類型):object 【function,array,object】
(在內(nèi)存中表現(xiàn)為一個(gè)指針,保存在堆中)
將一個(gè)對(duì)象的所有屬性均復(fù)制,并將該對(duì)象與原對(duì)象放在內(nèi)存中不同的位置,此時(shí),改變新對(duì)象的屬性不會(huì)對(duì)原對(duì)象造成影響,這種行為叫做深克隆。
我們還是先看淺克隆吧。。。
var people= {
name:"sun",
age:24,
hobby:["eat","shopping"],
son:{
age:3
}
}
//此處為淺克隆
function extendClone(oldObj) {
var newObj = {};
for(var i in oldObj){
newObj[i] = oldObj[i];
}
return newObj;
}
console.log(people);
var people1 = extendClone(people);
people1.name = "劉某某";
people1.hobby.push("看?。?);
console.log(people1);
var people2 = extendClone(people);
people2.name = "陳某某";
people2.hobby.push("游泳!");
console.log(people2);

淺克隆只是簡(jiǎn)單的復(fù)制對(duì)象,若對(duì)象其中一個(gè)屬性是引用值,由于引用型變量保存的是內(nèi)存的一個(gè)地址,所以后來的
hobby屬性,都指向內(nèi)存中的同一塊地址,最后輸出的結(jié)果同樣相同。從上面的例子也可以看出,
name等原始值的改變,并不會(huì)影響原對(duì)象中的原始值。
解決克隆引用值問題,還是需要深度克隆的!
for-in循環(huán)遍歷對(duì)象上的所有屬性,判斷是否為引用值,若是,進(jìn)行遞歸,直到所有屬性都為原始值為止。
拷貝出來后,就是一個(gè)全新對(duì)像,就和之前沒什么關(guān)系了,以前的改變也不能對(duì)新的產(chǎn)生影響!!
var people= {
name:"sun",
age:24,
hobby:["eat","shopping"],
son:{
age:3
}
}
function deepClone(oldObj,newObj){
var newObj = newObj||{};
for(var i in oldObj){
if(typeof oldObj[i]==='object'){
newObj[i] = (oldObj[i].constructor === Array) ? [] : {};//保存克隆后的引用值
deepClone(oldObj[i],newObj[i]);
}else {
newObj[i] = oldObj[i];
}
}
return newObj;
}
console.log(people);
var people1 = deepClone(people);
people1.name = "劉某某";
people1.hobby.push("看劇!");
console.log(people1);
var people2 = deepClone(people);
people2.name = "陳某某";
people2.hobby.push("游泳!");
console.log(people2);

一些擴(kuò)展
-
concat( )和slice( )
slice和concat方法都會(huì)返回一個(gè)新的數(shù)組,但是這兩個(gè)方法對(duì)于數(shù)組中的對(duì)象卻沒有執(zhí)行深復(fù)制
此時(shí)看起來好像是深度拷貝了,但是我們修改name值。。。var array = [[1,1,1],{name:"syx"},[3,3,3]]; var arrSlice = array.slice(0,2); console.log(array); //[[1,1,1],{name:"syx"},[3,3,3]]; console.log(arrSlice); //[[1,1,1],{name:"syx"}]
很容易看出,此時(shí)進(jìn)行的是淺復(fù)制arrSlice[1].name = "SYX"; console.log(array); //[[1,1,1],{name:"SYX"},[3,3,3]]; console.log(arrSlice); //[[1,1,1],{name:"SYX"}] - jQuery.extend( [deep ], target, object1 [, objectN ] )
deep
類型: Boolean
如果是true,合并成為遞歸(又叫做深拷貝)默認(rèn)值為false,表示淺拷貝。
target
類型: Object
對(duì)象擴(kuò)展。這將接收新的屬性。
object1
類型: Object
一個(gè)對(duì)象,它包含額外的屬性合并到第一個(gè)參數(shù).
objectN
類型: Object
包含額外的屬性合并到第一個(gè)參數(shù)
1.合并兩個(gè)對(duì)象,并修改第一個(gè)對(duì)象
var a= {
name:"sun",
age:24,
hobby:["eat","shopping"],
son:{
age:3
}
}
var b= {
name:"li",
age:28,
hobby:["游泳","看劇"],
son:{
age:5
}
}
$.extend(a, b);

2.當(dāng)繼承的對(duì)象屬性中有引用類型的時(shí)候,兩個(gè)對(duì)象同時(shí)指向一個(gè)對(duì)象,改變一個(gè)另一個(gè)也隨之改變。如果有相同屬性,后邊的會(huì)覆蓋前邊的
var a= {
name:"sun",
age:24,
son:{
age:3,
name:"小名"
}
}
var b= {
son:{
hobby:'游泳'
}
}
$.extend(true,a, b);
console.log(a);
