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;
}

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

原文地址:https://www.cnblogs.com/zhuxiaoweb/p/10001838.html