【ECMAScript】浅拷贝、深拷贝、浅比较、深比较的汇总

1. 前言

        日常开发中或阅读框架源码过程中,经常遇到浅拷贝、深拷贝、浅比较、深比较,本篇做一次汇总,对于数据类型在下一篇补上。

2. 浅拷贝shallowClone
const shallowClone = (obj) => {
    if(typeof obj !== 'object' && obj === null) {
        // 不是对象直接返回
        return obj;
    } else {
        // // 方式一:
        // return Array.isArray(obj) ? [ ...obj ] : { ...obj };

        // // 方式二:
        // return Array.isArray(obj) ? Object.assign([], obj) : Object.assign({}, obj);

        // // 方式三:浅拷贝数组
        // if(Array.isArray(obj)) {
        //     return obj.slice();
        // }
        // if(Array.isArray(obj)) {
        //     return obj.concat();
        // }
        // 方式四:
        const res = Array.isArray(obj) ? [] : {};
        const keys = Object.keys(obj);
        for(let key of keys) {
            if(Object.prototype.hasOwnProperty.call(obj, key)) {
                res[key] = obj[key];
            }
        }
        return res;
    }
};
3. 深拷贝deepClone 
const deepClone = (obj) => {
    if(typeof obj !== 'object' && obj === null) {
        // 不是对象直接返回
        return obj;
    } else {
        const res = Array.isArray(obj) ? [] : {};
        const keys = Object.keys(obj);
        for(let key of keys) {
            if(Object.prototype.hasOwnProperty.call(obj, key)) {
                res[key] = deepClone(obj[key]);
            }
        }
        return res;
    }
};
4. 浅比较shallowCompare
const shallowCompare = (objA, objB) => {
    if(Object.is(objA, objB)) {
        return true;
    }
    if(typeof objA !== 'object' || objA === null 
        || typeof objB !== 'object' || objB === null) {
        return false;
    }
    const keysA = Object.keys(objA);
    const keysB = Object.keys(objB);
    if(keysA.length !== keysB.length) {
        return false;
    }
    for(let key of keysA) {
        if(!Object.prototype.hasOwnProperty.call(objB, key)
         || !Object.is(objA[key], objB[key])) {
            return false;
        }
    }
    return true;
};
5. 深比较deepCompare
const deepCompare = (objA, objB) => {
    if(typeof objA !== 'object' || objA === null 
        || typeof objB !== 'object' || objB === null) {
        return false;
    }
    const keysA = Object.keys(objA);
    const keysB = Object.keys(objB);
    if(keysA.length !== keysB.length) {
        return false;
    }
    for(let key of keysA) {
        if(!Object.prototype.hasOwnProperty.call(keysB, key)) {
            return false;
        }
        if(Array.isArray(keysA[key]) && Array.isArray(keysB[key])) {
            if(!deepCompare(keysA[key], keysA[key])) {
                return false;
            }
        } else if((typeof keysA[key] === 'object' && !Array.isArray(keysA[key])) 
            && (typeof keysB[key] === 'object' && !Array.isArray(keysB[key]))) 
        {
            if(!deepCompare(keysA[key], keysA[key])) {
                return false;
            }
        } else if(!Object.is(keysA[key], keysB[key])) {
            return false;
        }
    }
    return true;
};

注:以上,如有不合理之处,还请帮忙指出,大家一起交流学习~

你可能感兴趣的:(前端开发,ecmascript,javascript,前端)