最近做项目的时候遇到一个对象深拷贝的问题,网上看了下发现最为简便的方法是JSON.stringify(),比如你要深拷贝一个对象,可以这么做:
var test={ a:"hello", b:"world", c:[ {dd:"css",ee:"cdd"}, {mm:"ff",nn:"ee"} ] }; var testCopy = JSON.parse(JSON.stringify(test))
这时你对testCopy变量的修改是不会影响到原来的test变量。
(注意,该方法有以下几个问题。
1、会忽略 undefined
2、会忽略 symbol
3、不能序列化函数
4、不能解决循环引用的对象
5、不能正确处理new Date()
6、不能处理正则
)
然后比较好奇的又去MDN查了下文档,发现JSON.stringify()还可以传可选的参数:
这里重点关注第二个参数,可以传一个函数或者数组。如上面文档所说,如果该参数是函数的话被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;嗯,感觉挺有用处的:
看例子,传函数:
比如,你只是想取该对象属性值为不为字符串的,就可以:
function replacer(key, value) { if (typeof value === "string") { return undefined; } return value; } var foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7}; var jsonString = JSON.stringify(foo, replacer);
结果为:{"week":45,"month":7}
.
传数组:
JSON.stringify(foo, ['week', 'month']); // '{"week":45,"month":7}', 只保留“week”和“month”属性值。
这么一来,我们可以很方便的对一个复杂对象数据进行简单的过滤筛选,甚至可以省略遍历属性的循环取值。