module.exports = deepCopy;
/**
* 可複製3種格式({}, [], Map)
*
* g8
*/
function deepCopy(data) {
// debugger;
var toString = Object.prototype.toString;
var clone;
var type = _getType(data);
// 若(data)是(不含子孫物件)
if (data == null || (type != 'array' && type != 'map' && !_isPlainObject(data))) {
clone = data;
return clone;
}
/* ---------------------------------- */
// data含有子孫物件
if (type == 'map') {
clone = new Map();
} else if (type == 'array') {
clone = [];
} else {
clone = {};
}
copyChild(clone, data);
//////////////////////////////////////////////////
/**
* 會進來的(data)一定是有子孫元素
*/
function copyChild(target, data) {
// debugger;
var clone;
var dataType = _getType(data);
var tar_getType = _getType(target);
/* ---------------------------------- */
if (tar_getType != dataType) {
throw new Error('要拷貝的數據型態不同');
} else if (dataType == 'map') {
// 若是(Map)
data.forEach(function(child, key) {
var childType = _getType(child);
if (childType != 'array' && childType != 'map' && !_isPlainObject(child)) {
// 若子物件是單純數據
target.set(key, child);
} else {
// 若(child)物件還攜帶有子孫
// (clone)必須與(child)同型態
clone = _getInitClone(childType);
/* ------------------------ */
// 遞回,把child拷貝到 clone
copyChild(clone, child);
target.set(key, clone);
}
});
} else if (dataType == 'array') {
// 若是(array)
data.forEach(function(child, key) {
var childType = _getType(child);
if (childType != 'array' && childType != 'map' && !_isPlainObject(child)) {
// 若子物件是單純數據
target[key] = child;
} else {
// 若子物件還攜帶有子孫
// (clone)必須與(child)同型態
clone = _getInitClone(childType);
/* ------------------------ */
// 遞回,把child拷貝到 clone
copyChild(clone, child);
target[key] = clone;
}
});
} else if (_isPlainObject(data)) {
// 若(data)是(PlainObject)
for (var key in data) {
if (data.hasOwnProperty(key)) {
var child = data[key];
var childType = _getType(child);
if (childType != 'array' && childType != 'map' && !_isPlainObject(child)) {
// 若子物件是單純數據
target[key] = child;
} else {
// 若子物件還攜帶有子孫
// (clone)必須與(child)同型態
clone = _getInitClone(childType);
/* ------------------------ */
// 遞回,把child拷貝到 clone
copyChild(clone, child);
target[key] = clone;
}
}
}
} else {
throw new Error('data have no child');
}
};
/* ---------------------------------- */
return clone;
////////////////////////////////////////////////////////////////////////////
function _getInitClone(type) {
var clone;
switch (type) {
case 'array':
clone = [];
break;
case 'map':
clone = new Map();
break;
default:
clone = {};
break;
}
return clone;
};
/* ====================================================================== */
function _getType(obj) {
var type = toString.call(obj) || '';
type = type.replace(/(^\s?\[object\s?)|(\]\s?$)/gi, '').toLowerCase();
return type;
};
/* ====================================================================== */
/**
* 只能是{}
*/
function _isPlainObject(obj) {
if (!obj || _getType(obj) !== "object") {
return false;
}
var constructorName = '';
try {
constructorName = obj.constructor.toString();
} catch (error) {}
// 'Object() {[native code]}'
if (!/function\s*Object\(\s*\)\s*\{\s*\[native\s*code\]\s*\}\s*$/gi.test(constructorName)) {
return false;
}
return true;
};
};