Javascriptは深コピーを実現します.
3196 ワード
Type関数
まず、getType関数を実現して要素をタイプ判定します.
参照のタイプについては、直接に他の変数に値を割り当てると、この2つの参照が同じアドレスを指すため、どちらの参照を変更するかは、他のいずれかに影響を与えます.私たちはオブジェクトをコピーして、このオブジェクトとの連絡を切りたい時は、深コピーを使います.一つの物体にとっては,多層構造があり得るので,再帰的にこの問題を解決するために使用できる.
広さ優先巡回
上は再帰的に深くコピーしていますが、木の広さを優先的に使うことができます.
深度コピーオブジェクトにはもう一つの解決方法があります.オブジェクトに関数が含まれていない場合、JSONを使って解析して逆解析すると、深度コピーオブジェクトが得られます.
まず、getType関数を実現して要素をタイプ判定します.
function getType(obj){
//tostring
var toString = Object.prototype.toString;
var map = {
'[object Boolean]' : 'boolean',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Function]' : 'function',
'[object Array]' : 'array',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
'[object Undefined]': 'undefined',
'[object Null]' : 'null',
'[object Object]' : 'object'
};
if(obj instanceof Element) {
return 'element';
}
return map[toString.call(obj)];
}
深度コピー(DeepClone)参照のタイプについては、直接に他の変数に値を割り当てると、この2つの参照が同じアドレスを指すため、どちらの参照を変更するかは、他のいずれかに影響を与えます.私たちはオブジェクトをコピーして、このオブジェクトとの連絡を切りたい時は、深コピーを使います.一つの物体にとっては,多層構造があり得るので,再帰的にこの問題を解決するために使用できる.
function deepClone(data){
var type = getType(data);
var obj;
if(type === 'array'){
obj = [];
} else if(type === 'object'){
obj = {};
} else {
//
return data;
}
if(type === 'array'){
for(var i = 0, len = data.length; i < len; i++){
obj.push(deepClone(data[i]));
}
} else if(type === 'object'){
for(var key in data){
obj[key] = deepClone(data[key]);
}
}
return obj;
}
functionタイプについては、ここで直接的に値を割り当てますか?それともメモリ値を共有しますか?これは関数がもっと多いのは機能を完成するので、入力値と戻り値があります.上の業務にとっては業務機能を完成することが多く、本当に関数を深くコピーする必要がありません.広さ優先巡回
上は再帰的に深くコピーしていますが、木の広さを優先的に使うことができます.
// , ,
function deepClone(data){
var obj = {};
var originQueue = [data];
var copyQueue = [obj];
// , ( )
var visitQueue = [];
var copyVisitQueue = [];
while(originQueue.length > 0){
var _data = originQueue.shift();
var _obj = copyQueue.shift();
visitQueue.push(_data);
copyVisitQueue.push(_obj);
for(var key in _data){
var _value = _data[key]
if(typeof _value !== 'object'){
_obj[key] = _value;
} else {
// indexOf ( indexOf )
var index = visitQueue.indexOf(_value);
if(index >= 0){
//
_obj[key] = copyVisitQueue[index];
} else {
originQueue.push(_value);
_obj[key] = {};
copyQueue.push(_obj[key]);
}
}
}
}
return obj;
}
JSON深度コピーオブジェクトにはもう一つの解決方法があります.オブジェクトに関数が含まれていない場合、JSONを使って解析して逆解析すると、深度コピーオブジェクトが得られます.