javascript 基本方法扩展
isEqual 仅比较实值的相等
js 中简单类型的比较是对具体值的比较;
而对于引用类型的比较,其比较的是引用值是否相等。
这里提供一种扩展方法,使得:
equal(1,1); equal(‘a’,’a’); 自然都返回为 true
equal({a:1},{a:1}) ; 也能返回为 true ; equal({a:1},{a:2}) 返回 false
// 获取复杂对象的类型
function getObjType(obj) {
  return Object.prototype.toString.call(obj)
    .slice(8, -1).toLowerCase();
}
// 对象是否为某一个类型
function isType(obj, type) {
  return getObjType(obj) === type;
}
/**
 * 仅比较值是否相等,不计较其内存地址是否同一个
 * equal({a:1},{a:1}) 返回 true
 * 这里不考虑函数的比较,直接执行默认的比较
 */
function isEqual(a, b) {
  var typeOfA = typeof a;
  var typeOfB = typeof b;
  if (typeOfA !== typeOfB) {
    return false;
  }
  if (typeOfA !== 'object') {
    return a === b;
  }
  if (typeOfA === 'object') {
    // 如果对象的具体类型不一致,直接返回
    var objTypeA = getObjType(a);
    if (objTypeA !== getObjType(a)) {
      return false;
    }
    // 如果是数组类型
    if (objTypeA === 'array') {
      if (a.length !== b.length) {
        return false
      }
      else {
        for (var i = 0, len = a.length; i < len; i++) {
          if (!isEqual(a[i], b[i])) {
            return false;
          }
        }
        return true;
      }
    }
    // 如果是object类型
    else if (objTypeA === 'object') {
      for (var attr in a) {
        if (!b.hasOwnProperty(attr)) {
          return false
        }
        if (!isEqual(a[attr], b[attr])) {
          return false;
        }
      }
    }
    // 如果是正则类型
    else if (objTypeA === 'regexp') {
      return a + '' === b + '';
    }
    // 如果是日期类型
    else if (objTypeA === 'date') {
      return +a == +b;
    }
  }
  return true;
}
// 测试使用
console.log(isEqual({ a: { c: /a/, d: 1 } }, { a: { c: /a/, d: 1 } })) // true
console.log(isEqual([1, 2, 3], [1, 2, 3])) // true
console.log(isEqual('1', 1)) // false
console.log(isEqual(/a/, /a/)) // true
console.log(isEqual(new Date(), new Date())) // true
var fn = function () { } 
console.log(isEqual(fn, fn)) // true平行结构和树状结构互转
- 原数据
var originData = [
   { title: '标题1', id: '1', pid: '0' },
   { title: '标题1-1', id: '1-1', pid: '1' },
   { title: '标题1-2', id: '1-2', pid: '1' },
   { title: '标题2', id: '2', pid: '0' },
   { title: '标题2-1', id: '2-1', pid: '2' },
   { title: '标题2-2', id: '2-2', pid: '2' },
   { title: '标题2-1-1', id: '2-1-1', pid: '2-1' },
   { title: '标题2-2-1', id: '2-2-1', pid: '2-2' },
   { title: '标题2-2-2', id: '2-2-2', pid: '2-2' },
   { title: '标题2-2-2-1', id: '2-2-2-1', pid: '2-2-2' },
   { title: '标题2-2-2-2', id: '2-2-2-2', pid: '2-2-2' },
 ];- 转换成树的结构的方法
默认用
children连接子级,可通过传递第三个参数linkkey的值改变
function toTree(arr, pid,linkKey='children') {
  var treeArr = [];
  var allTreeLeaf = arr.filter(item => item.pid === pid);
  allTreeLeaf.forEach(tree => {
    let _children = toTree(arr, tree.id)
    if (_children.length) {
      tree[linkKey] = _children;
    }
    treeArr.push(tree);
  })
  return treeArr;
}
// 使用
var formatTree = toTree(originData, '0');
console.log(formatTree)- 再将树形的结构展平
注意,此处的参数
treeData为引用关系,在展平的过程中,用到了delete,所以会影响到原数据,如果不想影响到原数据,需先拷贝要展平的数据,然后传入拷贝的数据。
 function flattenTree(treeData, linkKey) {
   var result = [];
   treeData.forEach(thrunk => {
     if (thrunk[linkKey] && thrunk[linkKey].length) {
       result = result.concat(flattenTree(thrunk.children, linkKey))
     }
     delete thrunk[linkKey]
     result = result.concat(thrunk);
   })
   return result;
 }
 // 使用,先使用转变为树,又展平回去。
 flattenTree(toTree(originData, '0'),'children');展平多维数组
var arr = [1,[2,[3,[4,[5]]]]];
function flatten(arr, result = []) {
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      flatten(arr[i], result);
    }
    else {
      result.push(arr[i])
    }
  }
  return result;
}
console.log(flatten(arr)); // [1,2,3,4,5]深拷贝
TODO

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号