返回列表

JavaScript对象深度克隆

默认分类 2013-01-24 19:58:37

看了很多 JavaScript对象深度克隆 的类似实现, 都不能解决自引用和循环嵌套问题, 于是只好自己动手稍稍改了一下, 吼吼

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>github.com/femvc</title>
<script type="text/javascript">
<!--
'use strict';
var bui = {};
/**
 * 对一个object进行深度拷贝
 *
 * @param {Any} source 需要进行拷贝的对象.
 * @param {Array} oldArr 源对象树索引.
 * @param {Array} newArr 目标对象树索引.
 * 
 * @return {Any} 拷贝后的新对象.
 */
bui.clone = function(source, oldArr, newArr) {
    var result = source, 
        i, 
        len,
        j,
        len2,
        exist = -1;
    oldArr = oldArr || [];
    newArr = newArr || [];

    if (!source
        || source instanceof Number
        || source instanceof String
        || source instanceof Boolean) {
        return result;
    } 
    else if (source instanceof Date) {
        result = new Date(source.getTime());
    } 
    else if ((source instanceof Array) || ('object' == typeof source)) {
        for (j=0,len2=oldArr.length; j<len2; j++) {
            if (oldArr[j] == source) {
                exist = j;
                break;
            }
        }
        if (exist != -1) {
            result = newArr[exist];
            exist = -1;
        }
        else {
            if (source instanceof Array) {
                result = [];
                oldArr.push(source);
                newArr.push(result);
                var resultLen = 0;
                for (i = 0, len = source.length; i < len; i++) {
                    result[resultLen++] = bui.clone(source[i], oldArr, newArr);
                }
            }
            if ('object' == typeof source) {
                result = {};
                oldArr.push(source);
                newArr.push(result);
                for (i in source) {
                    if (source.hasOwnProperty(i)) {
                        result[i] = bui.clone(source[i], oldArr, newArr);
                    }
                }
            }
        }
    } 

    return result;
};

var a,
    d;

function doit(){
    //Todo
    a = {b:{e:123},c:12};
    a.b.a = a;

    d = bui.clone(a);

    a.b.a.b.e = 789;
    alert(d.b.a.b.e); //123
}

//-->
</script>
</head>

<body><button type="button" onclick="doit()">doit</button>

</body>

</html>