zoukankan      html  css  js  c++  java
  • js深拷贝和相似对象对比方法--代码记录

    最近项目结束暂时得到了一段空闲的时间。回想项目中遇到的几个常用知识需要总结一下,这几天趁着还记得,抓紧时间记录一部分:

     一:相似对象对比方法 

     1. 项目中自己写的代码:

    /* 对象对比操作START */
    function _isBase(obj) {
      //检测是否非null,undefined,object,array等影响typeof表现形式的类型
      return obj != null && typeof (obj) !== 'undefined' && typeof (obj) !== 'object' && !(Object.prototype.toString.call(obj) === '[object Function]');
    }
    
    function compare(objA, objB) {
      //判断两个对象内容是否相等
      if(typeof objA == 'string' || typeof objB == 'string'){
        return objA==objB
      }
      if (objA === objB) {
        return true;
      }
      if (_isBase(objA) && _isBase(objA)) {
        if (objA !== objB) {
          return false
        }
      }
      let keysA = Object.keys(objA);
      let keysB = Object.keys(objB);
      if (keysA.length == keysB.length) {
        for (let i = 0; i < keysA.length; i++) {
          let item = keysA[i];
          if (objB.hasOwnProperty(item)) {
            if (!compare(objA[item], objB[item])) {
              return false;
            }
          } else {
            return false;
          }
        }
      } else {
        return false;
      }
      return true;
    }
    /* 对象对比操作END */

     现在看来这种写法再遇到 比较两个数组的情况时会对数组对象使用 Object.keys(arr) 遍历似乎不太友好。

     2.underscore的eq方法:

    var Utils = {};
    Utils.keys = function(obj) {
        if(Array.isArray(obj)) return [];
        else if(Object.keys) return Object.keys(obj)
    };
    Utils.has = function(obj, key) {
        return Object.prototype.hasOwnProperty.call(obj, key)
    }
    
    function equals(a, b, aStack, bStack) {
        var aStack = aStack ? aStack : [];
        var bStack = bStack ? bStack : [];
        //对原始类型数据进行比较,
        // 排除掉0和-0的相等性:
        if(a === b) {
            return a !== 0 || 1 / a === 1 / b;
        }
        //判断null和undefined,null==undefined->true
        if(a == null || b == null) {
            return a === b;
        }
    
        var className = Object.prototype.toString.call(a);
        if(className !== Object.prototype.toString.call(b)) {
            return false;
        }
        switch(className) {
            //统一转换为字符串后进行严格相等的判断:
            case '[object RegExp]':
            case '[object String]':
                return '' + a === '' + b;
                //应该把NaN看做相等,把0和-0看成不等
            case '[object Number]':
                if(+a !== +a) return +b !== +b;
                return +a === 0 ? 1 / +a === 1 / b : +a === +b;
                //直接判断
            case '[object Date]':
            case '[object Boolean]':
                return +a === +b;
        }
    
        //对数组和对象进行判断
        var areArrays = className === '[object Array]';
        if(!areArrays) {
            if(typeof a != 'object' || typeof b != 'object') return false;
    
            var aCtor = a.constructor,
                bCtor = b.constructor;
            if(aCtor !== bCtor && !(typeof aCtor === 'function' && aCtor instanceof aCtor &&
                    typeof bCtor === 'function' && bCtor instanceof bCtor) &&
                ('constructor' in a && 'constructor' in b)) {
                return false;
            }
        }
        var length = aStack.length;
        while(length--) {
            if(aStack[length] === a) return bStack[length] === b;
        }
    
        aStack.push(a);
        bStack.push(b);
        var size, result;
        if(areArrays) {
            size = a.length;
            result = size === b.length;
            if(result) {
                while(size--) {
                    if(!(result = equals(a[size], b[size], aStack, bStack))) break;
                }
            }
        } else {
            var keys = Utils.keys(a),
                key;
            size = keys.length;
            result = Utils.keys(b).length === size;
            if(result) {
                while(size--) {
                    key = keys[size];
                    if(!(result = Utils.has(b, key) && equals(a[key], b[key], aStack, bStack))) break;
                }
            }
        }
        aStack.pop();
        bStack.pop();
        return result;
    }

     一:相似对象对比方法 

     1. 项目中自己写的代码:

    function deepCopy(obj) { //深拷贝
        return JSON.parse(JSON.stringify(obj))
    }

     2. 收集的网友代码:

    function deepCopy(data) {//深拷贝方法一
        let vv = null
        if(typeof data == 'object' && data !== null) {
            vv = data.constructor === Array ? [] : {}
            for(let v in data) {
                vv[v] = deepCopy(data[v])
            }
        } else {
            vv = data
        }
        return vv
    }
    
    
    //深拷贝方法二
    function getType(obj) {
        var str = Object.prototype.toString.call(obj);
        var map = {
            '[object Boolean]': 'boolean',
            '[object Number]': 'number',
            '[object String]': 'string',
            '[object Function]': 'function',
            '[object Array]': 'array',
            '[object Date]': 'date',
            '[object RegExp]': 'regExp',
            '[object Undefined]': 'undefined',
            '[object Null]': 'null',
            '[object Object]': 'object'
        }
        if(obj instanceof Element) { //判断是否是dom元素,如div等
            return "element";
        }
        return map[str];
    }
    
    //深拷贝函数
    function deepCopy(p) {
        var obj;
        var str = getType(p);
        if(str == 'array') {
            obj = [];
            for(var i = 0; i < p.length; i++) {
                obj.push(arguments.callee(p[i])); //回调自己
            }
        } else if(str == 'object') {
            obj = {};
            for(var i in p) {
                obj[i] = arguments.callee(p[i]);
            }
        } else {
            return p;
        }
        return obj;
    }

    其他常见问题总结放在下一次发布了。

  • 相关阅读:
    PHP base_convert() 函数详解
    PHP中位运算符
    MySQL中SQL Mode的查看与设置
    HTML 字符实体详情
    php7中 ?? 和 ?: 的区别
    正则表达式详解
    PHP sprintf() 函数详解
    php-config——PHP配置信息的查看
    无界工作记录
    CMake根据平台移植检查设置文件编译选项
  • 原文地址:https://www.cnblogs.com/zhuxiaoweb/p/10001838.html
Copyright © 2011-2022 走看看