var clone = (
function() {
var classof =
function(o) {
if (o ===
null) {
return
"null";
}
if (o ===
undefined) {
return
"undefined";
}
var className =
Object.prototype.toString.call(o).slice(
8,
-1);
return className;
};
var references =
null;
var handlers = {
'RegExp':
function(reg) {
var flags =
'';
flags += reg.global ?
'g' :
'';
flags += reg.multiline ?
'm' :
'';
flags += reg.ignoreCase ?
'i' :
'';
return
new
RegExp(reg.source, flags);
},
'Date':
function(date) {
return
new
Date(+date);
},
'Array':
function(arr, shallow) {
var newArr = [],
i;
for (i =
0; i < arr.length; i++) {
if (shallow) {
newArr[i] = arr[i];
}
else {
if (references.indexOf(arr[i]) !==
-1) {
continue;
}
var handler = handlers[classof(arr[i])];
if (handler) {
references.push(arr[i]);
newArr[i] = handler(arr[i],
false);
}
else {
newArr[i] = arr[i];
}
}
}
return newArr;
},
'Object':
function(obj, shallow) {
var newObj = {}, prop, handler;
for (prop
in obj) {
if (obj.hasOwnProperty(prop)) {
if (shallow) {
newObj[prop] = obj[prop];
}
else {
if (references.indexOf(obj[prop]) !==
-1) {
continue;
}
handler = handlers[classof(obj[prop])];
if (handler) {
references.push(obj[prop]);
newObj[prop] = handler(obj[prop],
false);
}
else {
newObj[prop] = obj[prop];
}
}
}
}
return newObj;
}
};
return
function(obj, shallow) {
references = [];
shallow = shallow ===
undefined ?
true :
false;
var handler = handlers[classof(obj)];
return handler ? handler(obj, shallow) : obj;
};
}());
(
function() {
var date =
new
Date();
var reg =
/hello word/gi;
var obj = {
prop:
'this ia a string',
arr: [
1,
2,
3],
o: {
wow:
'aha'
}
};
var refer1 = {
arr: [
1,
2,
3]
};
var refer2 = {
refer: refer1
};
refer1.refer = refer2;
var cloneDate = clone(date,
false);
var cloneReg = clone(reg,
false);
var cloneObj = clone(obj,
false);
alert((date !== cloneDate) && (date.valueOf() === cloneDate.valueOf()));
alert((cloneReg !== reg) && (reg.toString() === cloneReg.toString()));
alert((obj !== cloneObj) && (obj.arr !== cloneObj.arr) && (obj.o !== cloneObj.o) && (
JSON.stringify(obj) ===
JSON.stringify(cloneObj)));
clone(refer2,
false);
alert(
"I'm not dead yet!");
}());