美文网首页
深度比较两个javaScript对象

深度比较两个javaScript对象

作者: __越过山丘__ | 来源:发表于2018-12-25 16:24 被阅读0次
    function deepCompare(x, y) {
        var i, l, leftChain, rightChain;
    
        function compare2Objects(x, y) {
            var p;
    
            // remember that NaN === NaN returns false
            // and isNaN(undefined) returns true
            if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
                return true;
            }
    
            // Compare primitives and functions.     
            // Check if both arguments link to the same object.
            // Especially useful on the step where we compare prototypes
            if (x === y) {
                return true;
            }
    
            // Works in case when functions are created in constructor.
            // Comparing dates is a common scenario. Another built-ins?
            // We can even handle functions passed across iframes
            if ((typeof x === 'function' && typeof y === 'function') ||
                (x instanceof Date && y instanceof Date) ||
                (x instanceof RegExp && y instanceof RegExp) ||
                (x instanceof String && y instanceof String) ||
                (x instanceof Number && y instanceof Number)) {
                return x.toString() === y.toString();
            }
    
            // At last checking prototypes as good as we can
            if (!(x instanceof Object && y instanceof Object)) {
                return false;
            }
    
            if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
                return false;
            }
    
            if (x.constructor !== y.constructor) {
                return false;
            }
    
            if (x.prototype !== y.prototype) {
                return false;
            }
    
            // Check for infinitive linking loops
            if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
                return false;
            }
    
            // Quick checking of one object being a subset of another.
            // todo: cache the structure of arguments[0] for performance
            for (p in y) {
                if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
                    return false;
                } else if (typeof y[p] !== typeof x[p]) {
                    return false;
                }
            }
    
            for (p in x) {
                if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
                    return false;
                } else if (typeof y[p] !== typeof x[p]) {
                    return false;
                }
    
                switch (typeof(x[p])) {
                    case 'object':
                    case 'function':
    
                        leftChain.push(x);
                        rightChain.push(y);
    
                        if (!compare2Objects(x[p], y[p])) {
                            return false;
                        }
    
                        leftChain.pop();
                        rightChain.pop();
                        break;
    
                    default:
                        if (x[p] !== y[p]) {
                            return false;
                        }
                        break;
                }
            }
    
            return true;
        }
    
        if (arguments.length < 1) {
            return true; //Die silently? Don't know how to handle such case, please help...
            // throw "Need two or more arguments to compare";
        }
    
        for (i = 1, l = arguments.length; i < l; i++) {
    
            leftChain = []; //Todo: this can be cached
            rightChain = [];
    
            if (!compare2Objects(arguments[0], arguments[i])) {
                return false;
            }
        }
    
        return true;
    }

    相关文章

      网友评论

          本文标题:深度比较两个javaScript对象

          本文链接:https://www.haomeiwen.com/subject/oaiflqtx.html