javascript淺拷貝深拷貝詳解
阿新 • • 發佈:2017-10-25
clas ret utf 復制代碼 alt 都是 body 理解 simple
一、淺拷貝
淺拷貝在現實中最常見的表現在賦值上面,例如
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試</title> </head> <body> <script type="text/javascript"> //第一個數組 var test=["1","2","3"]; //第二個數組 var test2=[]; test2=test; test2[1]="two"; console.log(test);//運行的結果是["1","two","3"] </script> </body> </html>
從上面的例子,我們修改test2數組的值,最後打印test數組,發現test也跟著改變了。
其實這個就是一個最淺的淺拷貝,相當於test2=test這個階段是在將test數組中的存儲地址索引賦值給test2數組,所以兩個數組都是指向同一塊存儲地址中去。
除了這種方法可以實現淺拷貝,還有使用slice和concat進行淺拷貝
例如:我們測試一次slice這個方法(可從已有的數組中返回選定的元素為新數組)
<script type="text/javascript"> var arr=["demo1","demo2","demo3"]; var arr2=arr.slice(0); arr2[1]="test"; console.log(arr);//["demo1","demo2","demo3"] console.log(arr2);//["demo1","test","demo3"] </script>
從上面的例子我們可以看出,使用slice方法對數組進行了深度拷貝,
同理,concat的用法如下(用於連接兩個或多個數組為新數組)
<script type="text/javascript"> var arr=["demo1","demo2","demo3"]; var arr2=arr.concat(); arr2[1]="test"; console.log(arr);//["demo1","demo2","demo3"] console.log(arr2);//["demo1","test","demo3"] </script>
為何這樣已經算得上是深拷貝的東西,我又稱之為淺拷貝呢?
對於Slice和concat這兩個方法來說都是淺拷貝,只能拷貝數組中的第一層
二、深拷貝
1.通過內置的js函數
function deepCopy(o){ return JSON.parse(JSON.stringify(o)); } var a = {a:1,b:2,c:3}; var b = deepCopy(a); b.a = 4; alert(a.a); //1 alert(b.a); //4,將b.a賦值為4,不會影響到a對象,a.a仍是1
這種方式很好理解,對一個Object對象而言,
先使用內置的JSON.stringify()函數,將其轉化為字符串 "{"a":1,"b":2}"
此時生成的字符串已經和原對象沒有任何聯系了,再通過JSON.parse()函數,將生成的字符串轉化為一個新的對象。 {a: 1, b: 2}
而在新對象上的操作與舊對象是完全獨立的,不會相互影響。這種方法的優點就是簡單易懂,使用js內置函數來實現,不需要太大的開銷。
2.以通過自己的方法實現,就是遍歷數組或對象,返回新數組或者對象。
var simpleCopy = function(o){ if (o instanceof Array) { var n = []; for (var i = 0; i < o.length; ++i) { n[i] = o[i]; } return n; } else if (o instanceof Object) { var n = {} for (var i in o) { n[i] = o[i]; } return n; } }
3.如何實現拷貝包含對象或者數組的這種情況呢?那麽就通過遞歸拷貝來實現。
var deepCopy = function(o) { if (o instanceof Array) { var n = []; for (var i = 0; i < o.length; ++i) { n[i] = deepCopy(o[i]); } return n; } else if (o instanceof Object) { var n = {} for (var i in o) { n[i] = deepCopy(o[i]); } return n; } else { return o; } }
javascript淺拷貝深拷貝詳解