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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值