關於物件深拷貝和陣列去重的問題

2021-09-08 07:25:50 字數 1646 閱讀 3162

中秋最後一天假期,還是憋屈在家裡,沒事可做,發發關於兩個看似很基礎卻又很有意義的兩個問題的一點感想,如題...

一.物件深拷貝:

對應的淺拷貝,物件是通過位址指向來獲得引用的,所以單純的用乙個新物件指向源物件就是淺拷貝,對新物件的操作同樣會影響的源物件。好比小明有個u盤,裡面裝有一些資料,一天,小紅也需要這個u盤裡的資料,於是拿過來改了裡面的資料,結果小明再用時,裡面資料就變了,因為兩個人用的其實是同乙個u盤嘛... 如下:

var obj = ;

var obj1 = obj;

obj.a = 'a1';

alert(obj.a);

alert(obj1.a);

執行

那麼怎麼樣才能資料各自私有而不影響對方呢,顯而易見嘛,讓小紅也去買個u盤,並把資料也拷乙份到她的u盤裡,各用個的就行了。於是:

function clone(myobj)

var obj = ;

var obj1 = obj;

var obj2 = clone(obj);

obj.a = 'a1';

alert(obj.a);

alert(obj1.a);

alert(obj2.a);

執行

至此,區別也很明顯了,obj1淺拷貝由於是訪的同乙個物件,故改變源物件obj,新物件obj1也隨之改變。而深拷貝obj2是新建了乙個物件例項,與源物件obj互不干擾。

二.關於陣列去重

網上很流行一種解法,如下:

array.prototype.filter = function(),result=,ci;ci=this[i++];)

return result;

}var aa=['1','2','3','1','2'];

alert(aa.filter());

執行

它其實是用了物件的特性,把每個陣列元素當做乙個物件的屬性來判斷是否存在,這樣做有個好處是不用二次遍歷陣列。然而,乍一看結果沒問題,可是一旦陣列裡有了number,布林值,物件等作為元素的時候,就會發現問題了。

原因在於:物件則要求其屬性值必須為字串,如果提供給物件的屬性不是字串,那麼則會自動呼叫 tostring 方法轉化為字串形式,於是,嚴格來講,這種方法只能在陣列元素全為字串時才成立

我們再看看jquery的原始碼是怎麼實現陣列去重的方法的:

unique: function( array ) ;  

try

} } catch( e )

return ret;

},

乍一看,其實思路跟我上面說的方法是一樣的,可是別忘了很重要的一點,var id = jquery.data( array[ i ] );這一句,其實是把每個陣列元素都轉換成了節點陣列再做的判斷。

所以,如果把安全性放在首位,效率次之的話,陣列去重還是應該老老實實二次遍歷陣列,如下:

function undulpicate(array){

for(var i=0;i當然,如果能確定陣列元素型別,大可不必這樣做,畢竟二次遍歷在資料量大的時候是個不小的消耗。。

此外,貌似hash查詢可以減少一次遍歷...具體還沒想過...唉,今天就到此位置吧

陣列深拷貝 物件的深拷貝 陣列去重

1 for 迴圈實現陣列的深拷貝 var arr 1,2,3,4,5,6 var arr2 copyarr arr function copyarr arr var obj2 copyobj obj function copyobj obj for var key in obj return res...

利用遞迴實現,多維陣列和物件的深拷貝,深去重

利用遞迴實現,多維陣列和物件的深拷貝,深去重 二二二物件轉殖 let map let hebei shijiazhuang baoding zhangjiakou shijiazhuang 第一種 物件深拷貝 let deepclone obj for key in obj return t let...

淺拷貝和深拷貝以及陣列去重示例

1.淺拷貝 var obj1 var obj2 淺拷貝只拷貝第一層屬性,引用型別資料位址是相同的 因此存在資料共享問題 遍歷obj1 for var key in obj1 深拷貝 解決資料共享問題 function deepcopy source,target 判斷是陣列還是物件 deepcopy...