昨天教導新人的時候,發現她不了解複製資料時的區別,以為a=b之後賦值之後之後就沒有關聯了,因此今天寫這篇文章自己整理一下這中間要注意的東西。這篇先寫因為資料型別導致的複製區別,下篇寫深拷貝淺拷貝。
在**中,經常會用到需要將a賦值給b的情況。但是a的值得型別往往會影響到拷貝之後a、b之間是否會有聯絡。
js的基礎資料型別有以下幾種:
undefined、null、布林值(boolean)、字串(string)、數值(number)、物件(object),es6又新增了一種symbol。
引用資料型別有
當a為基礎資料型別時,b複製了a的值,然後再改變a的值,最後列印時,a的值改變了,但是b的值不會改變。這種實際上是在記憶體中給b另外建立了乙個控制項儲存它的資料,,所以之後a不管再怎麼變都不會影響到b了。
舉例:就和我們平時複製資料夾一樣,複製了乙個一抹一樣的檔案,但是之後分別這兩個檔案的增刪改查都不會影響到對方。
let a =12;
let b = a;
a =13
;console.
log(
'a:'
+ a)
;console.
log(
'b:'
+ b)
;
當a為引用資料型別時,如object型別,b複製了a的值之後,再改變a的值,之後列印a、b,可以發現a、b的值都改變了。這是因為引用資料型別在棧記憶體中儲存的實際上是物件在堆記憶體中的引用位址。通過這個引用位址可以快速查詢到儲存中堆記憶體中的物件。然後在複製時給b的時乙個引用位址,但是a與b的引用位址指向的是同乙個記憶體,也就是a之前所指向的記憶體位址,所以只要改變a或者b,改變的都是他們的記憶體位址中的值,因此只要有改動,兩個都會一起發生改變。舉個例子:
引用資料型別複製時的情況就像是一間房間,有好幾個入口,儲存資料所在的記憶體就是房間,本來只有a乙個入口,後來又增加了b這個入口a與b就是這個房間的不同的入口,當從a或者b入口進去把房間裡的家具改變之後,房間沒有變,入口也沒有變,但是再從a或者b進去之後看到的房間內部都已經變化了,但依然是同乙個房間。
let a =
;let b = a;
a.id =
'000002'
;a.id =
'小王'
;console.
log(
'列印a的值');
console.
log(a)
;console.
log(
'列印b的值');
很多時候複製後的資料並不想和原來的資料關聯起來,這個時候就要對引用資料型別的複製進行處理了,原理就是把引用資料型別中的每乙個基礎型別乙個個複製過去。這樣就會另外分配乙個記憶體位址,不會和之前的共用同乙個了。
let a =
;// 把a的值複製過去
let b =
;a.id =
'000002'
;a.id =
'小王'
;console.
log(
'列印a的值');
console.
log(a)
;console.
log(
'列印b的值');
console.
log(b)
;
結果如下,a改變後b沒有改變,依然是之前複製好的值,
但是這種是最簡單的情況,很多時候要複製的引用型別的屬性值很多,甚至還可能巢狀。這種時候如果乙個個手動拆開來複製的話太過麻煩,就需要優化寫法了,比如乙個遞迴遍歷物件的方法,這裡不再贅述,另起一篇詳細描述。
let a =
};
資料庫拷貝的注意事項
俺是潛水員,從來不發帖子的,今天偶然回乙個帖子,發現寫太多了,決定乾脆發成主貼吧 拋磚引玉 剛好可以和各位討論討論滲透方面的問題。帖子寫的很亂,沒做什麼修改,就是乙個回帖,勿見怪。注意 本文本多,非滲透愛好者,勿看。原貼大致問題 樓主想拷貝對方內網資料庫的資料,大概150g,而後又拿到了幾台伺服器的...
SQL 複製過程的注意事項
1 設定共享複製目錄 puter machine c 如果伺服器取消過預設的共享 則會失敗 此時新建乙個目錄,並賦予許可權,目錄改為 puter machine 共享目錄名 2 建立用於發布應用的windows賬號 3 在配置分發伺服器時遭遇了 錯誤18483 提示因為distributor adm...
js的基礎注意事項
undefined boolean string number null object記住一下幾個 1 alert undefined null 為true 2 isnan 數值 對數值裡面的數看是否可以轉換為數字,若可以則nan 數值 為true,否則為false.舉例如下 isnan 10 為t...