1. 程式人生 > >javascript的深複製和淺複製(深度拷貝和淺拷貝)

javascript的深複製和淺複製(深度拷貝和淺拷貝)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js深度複製淺顯複製</title>
</head>
<body>
<h1>js的深複製和淺複製</h1>
<h2>深複製和淺複製最根本的區別在於是否是真正獲取了一個物件的複製實體,而不是引用,
1)深複製在計算機中開闢了一塊記憶體地址用於存放複製的物件,
  2)而淺複製僅僅是指向被複制的記憶體地址,如果原地址中物件被改變了,那麼淺複製出來的物件也會相應改變</h2>
<h2>因為淺複製只會將物件的各個屬性進行依次複製,並不會進行遞迴複製,而 JavaScript 儲存物件都是存地址的,所以淺複製會導致xin 和 jiu 指向同一塊記憶體地址。</h2>
<p>JS中物件分為基本型別和複合(引用)型別,基本型別存放在棧記憶體,複合(引用)型別存放在堆記憶體。</p>
<p>堆記憶體用於存放由new建立的物件,棧記憶體存放一些基本型別的變數和物件的引用變數</p>
<p>而對於物件這種記憶體佔用比較大的來說,直接讓複製的東西等於要複製的,那麼就會發生引用,因為這種複製,只是將複製出來的東西的指向指向了要複製的那個東西,簡單的說,就是兩個都同時指向了一個空間,如果改變其中一個,另一個也會發生變化。這就發生了引用。</p>
<p>引用只發生在物件的身上</p>
<p>那麼對於陣列,ES6我們複製有新的兩種方法,不會發生引用。</p>
<p>Array.from(要複製的陣列);</p>
<p>es6 複製方法1 </p>
<p>
<pre>
var arr1=[1,2,3];
var arr2=Array.from(arr1);
arr1.push(4);
alert(arr1);  //1234
alert(arr2);  //123
arr2.push(5);
alert(arr1);  //1234
alert(arr2);  //1235
</pre>
</p>
<p>方法2</p>
<p> var arr1=[1,2,3];
var arr2=[...arr1];</p>
<p>方法3或者是通過迴圈來複制:</p>
<p> for(var name in json1){
  json2[name]=json1[name];
}</p>
<script type="text/javascript">
// 直接拷貝的方法是淺拷貝
    var old = [1,2,3,4];
    var mynew = old;
    mynew[0]="11";
    console.log("老的陣列是"+old); //[1,2,3,4];
    console.log("新的是"+mynew); //[1,2,3,4];
    // 這是淺複製,因為 新的和老的陣列都是 一樣改變的;
    // 當我們不想改變原來的陣列的時候,可以使用js 自帶的slice 和concat 等  他們 操作過後 原來的陣列還是不變的
     //例如
     var oldarr = [1,2,3,4,5];
     var newarr = oldarr.slice(0,2);
     console.log("原來的陣列是"+oldarr);// [1,2,3,4,5];
     console.log("新陣列是"+newarr);//[1,2]
  // 物件de深淺拷貝
var a={name:'yy',age:26};
var b=new Object();
b.name=a.name;
b.age=a.age;
a.name='xx';
console.log(b);//Object { name="yy", age=26}
console.log(a);//Object { name="xx", age=26}


</script>
</body>
</html>