javascriptの浅いコピー、深いコピー
2884 ワード
以前はjavascriptに対して浅いコピーで和深にコピーしたのは生半可です.今はよく整理してください.
まず、参照型の変数について知っています.変数が実際に記憶されているのは、メモリのアドレスを指している変数のポインタです.以下のコードの中で
最初の話に戻ります.和深コピーとは何かを見てみます.
浅いコピーは簡単なコピー参照です.(オブジェクトの割当操作さえも、浅いコピーと見なすことができる)
SE 6には、オブジェクトのマージのためにObject.assignがあり、ソースオブジェクトのすべてのエニュメレーション属性を対象オブジェクトにコピーします.内部実装は、実際には浅いコピーであり、ターゲットの原型を削除する方法である.
深度コピーの実現方法については大同小異ですが、ここでは二つの方法を提供します.
まず、参照型の変数について知っています.変数が実際に記憶されているのは、メモリのアドレスを指している変数のポインタです.以下のコードの中で
var a = {
name:'david'
}
var b = a
実際にはaとbはメモリ内の変数を指しているポインタを保存しています.bに対する修正は、aも同時に変化します.b.name = 'jimmy'
console.log(a.name)//'jimmy'
同じように、Javascriptの学生を困らせる例がもう一つあります.jsでは関数のパラメータが値によって伝達されることを知っている.次の例ではvar value1 = "test"
var value2 = {
name:'david'
}
function a(v1,v2){
v1 = "change"
v2.name = "jimmy"
}
a(value1,value2)
console.log(value1)//test
console.log(value2)//{name:"jimmy"}
aを実行した後、value 1は変化しませんでしたが、value 2のnameは変わりました.関数実行時には、まず変数v 1,v 2を関数内部に初期化するからです.value 1は基本タイプなので、直接数値をコピーしました.value 2では参照型の変数をコピーします.コピー操作は実際にポインタをコピーしています.したがって、内部のv 2に対する操作はメモリ内の変数に影響を及ぼします.したがって、外部関数のvalue 2が変化した.最初の話に戻ります.和深コピーとは何かを見てみます.
浅いコピーは簡単なコピー参照です.(オブジェクトの割当操作さえも、浅いコピーと見なすことができる)
function copy(target){
var obj = Array.isArray(target)?[]:{}
for(let i in target){
obj[i] = target[i]
}
return obj
}
var david = {
name:'david',
info:{
birth:1993
}
}
var david_copy = copy(david)
david_copy.info===david.info//true
(いくつかの例では、浅いコピーは対象の原型の方法を削除しますが、個人的には深くする必要はないと思います.原型を取り除く方法は浅いコピーの二つの実現方法だけです.プロジェクトのニーズを見て、どれを使うかを決められます.)SE 6には、オブジェクトのマージのためにObject.assignがあり、ソースオブジェクトのすべてのエニュメレーション属性を対象オブジェクトにコピーします.内部実装は、実際には浅いコピーであり、ターゲットの原型を削除する方法である.
var david_copy = Object.assign({},david)
david_copy.info===david.info//true
深くコピーすればよく分かります.まったく新しい相手が生まれました.浅いコピーは1つのオブジェクトの属性だけをコピーし、深いコピーはすべての階層にコピーされます.深度コピーの実現方法については大同小異ですが、ここでは二つの方法を提供します.
function deepCopy(target){
return JSON.parse(JSON.stringify(target))
}
しかし、この方法には弊害があります.1.関数をコピーできません.2.プロトタイプの方法と属性をコピーできません.function deepCopy(target){
var isArrayOrObject = function(o){
return Object.prototype.toString.call(o)=="[object Array]"||Object.prototype.toString.call(o)=="[object Object]"
}
if(!isArrayOrObject(target)){
//
return target
}
var createObj = function(o){
return Object.prototype.toString.call(o)=="[object Array]"?[]:{}
}
var obj = createObj(target)
var copy = function(target,container){
for(var i in target){
if(isArrayOrObject(target[i])){
container[i] = createObj(target[i])
copy(target[i],container[i])
}else{
container[i] = target[i]
}
}
return container
}
return copy(target,obj)
}
補足して、domの操作の中にも深いコピーと浅いコピーがあります.clone Nodeは、ノードをコピーするために使用され、パラメータtrueに入ると、そのサブ世代をコピーします(イベントをクリックするなど、javascript処理プログラムをコピーしません).パラメータを読み込まない、またはfalseではノード自体をコピーします.