documentcloud/underscore — pull request #731 by natefaubion (2012-09-01 18:40:31+00:00)
Title: Deep clone alternative with _.cloneJSON

The issue of deep cloning comes up frequently and is usually dismissed because its so unclear as to what to do with it. Here's an implementation that doesn't try to do too much and acts predictably by producing the same result as `JSON.parse(JSON.stringify(obj))`. Here is my test object for comparison:

```js
function A () {this.foo = "bar";}
A.prototype.method = function () {};

function testObj () {
return {
"number": 42,
"string": "foo",
"boolean": true,
"array": [1,2,function(){}],
"object": {foo: "bar"},
"arguments": arguments,
"function": function () {},
"instance": new A(),
"date": new Date(),
"regexp": /^$/g,
"math": Math,
"nan": NaN,
"null": null,
"infinity": Infinity
};
}
console.log(JSON.stringify(testObj()));
```

Key transformations include:
* functions are changed to undefined (which means the key is omitted from the object)
* undefined values are changed to null within arrays,
* arguments, regexps, and Math are changed to empty objects
* NaN and Infinity are changed to null
* Dates are changed to ISO strings
* Instances lose their prototypes and methods

http://jsperf.com/json-clone/2

Performance is on par with jQuery's deep extend, but funnily enough, significantly slower than stringifying and parsing the value.

I think this solves the most common (by far) use case of just copying data structures, but I don't know if the performance implications make it worth including. What does everyone think?