underscore的_.clone只实现了对象的第一层拷贝,即是浅复制,但是实际有时候需要进行对象的深拷贝。所以这里扩展了一个_.deepClone。如发现代码有不妥之处,欢迎批评指正,谢谢。
<script src="underscore-1.8.2.js"></script>
<script>
var obj = {
a: [{x: 1}, {x: {x: [{z: 1}]}}],
b: [{y: null}, {y: function() {}}]
}
var objNull = {x: null, y: undefined};
var arr = [[{y: null}, {y: function() {}}], [{x: 1}, {x: {x: [{z: 1}]}}]];
_.deepClone = function(obj) {
<span style="white-space:pre"> </span>var cloneObj;
if (!_.isObject(obj) || typeof obj === 'function') {
<span style="white-space:pre"> </span>return obj;
<span style="white-space:pre"> </span>}
cloneObj = _.isArray(obj) ? [] : {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (!_.isObject(obj[i])) {
// obj[i]为null和undefined都会进入这里
cloneObj[i] = obj[i];
} else {
cloneObj[i] = _.deepClone(obj[i]);
}
}
}
return cloneObj;
};
var obj1 = _.clone(obj);
var obj2 = _.deepClone(obj);
obj.a[1].x.x[0].z = 3;
console.log(obj1); // 相应的值变为3。所以这只是实现了浅复制
console.log(obj2); // 相应的值不变。所以这里实现了深拷贝
console.log(_.isArray(arr[0])); // 输出true,表示该对象初始状态是一个数组
var cloneArr = _.deepClone(arr);
console.log(cloneArr);
console.log(_.isArray(cloneArr[0])); // 输出true,表示这个深拷贝方法是正确的,不会影响对象的原型链
</script>