【JS】深拷贝实现

一、BUG

WEB平台上一直在刻意的避开深拷贝,一直使用JSON.parse(JSON.stringify(Object))避开深拷贝的问题。知道今天碰见个BUG,JSON将function转化为了字符串,排到这个BUG时,憔悴…
若是Node.js平台的话,一直现成的轮子等着挑,可惜是WEB,不太敢乱引入,手写一个<_<

二、深拷贝

/**
 * 深拷贝
 * 支持类型:Boolean,Number,String,null,undefined,Array,Object
 * @param {*} obj 
 */
function deepClone(obj) {

    if (isBaseDataType(obj)) {
        return obj;
    }

    /**
     * 判断数据类型
     * 不考虑Symbol类型
     * @param {*} obj 
     */
    function judgeType(_obj) {
        return _obj === null ? 'null' : _obj instanceof Array ? 'array' : typeof _obj !== 'object' ? typeof _obj : 'object';
    }

    /**
     * 基本数据类型判断
     * @param {*} obj 
     */
    function isBaseDataType(_obj) {
        var types = ['boolean', 'number', 'string', 'function', 'null', 'undefined'];
        var type = judgeType(_obj);
        return types.indexOf(type) !== -1;
    }

    /**
     * 数组深拷贝
     * @param {*} _obj 
     * @param {*} res 
     */
    function _cloneArry(_obj) {
        var res = [];
        for (var i = 0, len = _obj.length; i < len; i++) {
            var value = _obj[i];
            if (isBaseDataType(value)) {
                res.push(value);
            } else if (judgeType(value) === 'object') {
                res.push(_cloneObj(value));
            } else if (judgeType(value) === 'array') {
                res.push(_cloneArry(value));
            }
        }
        return res;
    }

    /**
     * 对象深拷贝
     * @param {*} _obj 
     * @param {*} res 
     */
    function _cloneObj(_obj) {
        var res = {};
        for (var attr in _obj) {
            var value = _obj[attr];
            if (isBaseDataType(value)) {
                res[attr] = value;
            } else if (judgeType(value) === 'object') {
                res[attr] = _cloneObj(value);
            } else if (judgeType(value) === 'array') {
                res[attr] = _cloneArry(value);
            }
        }
        return res;
    }

    if (judgeType(obj) === 'array') {
        return _cloneArry(obj);
    } else {
        return _cloneObj(obj);
    }
}

另外补充一句:Object.assgin,这个接口真不是深拷贝,也是个不大不小的坑

你可能感兴趣的:(WEB前端,深拷贝)