js中判断Object、Array、Function等引用类型对象是否相等

  在迭代中,我们还要注意的是,对象或者数组中的元素可能是一个任意值——除了原始类型值、object、arrray外,这个值还可能是一个方法、一个DOM对象或者window对象,可能你已经注意到了,有部分引用类型是不能进行迭代的,需要分支判断,代码如下:

  

复制代码 代码如下:

  function compare(a,b){

  var

  pt = /undefined|number|string|boolean/,

  fn = /^(function\s*)(\w*\b)/,

  cr = "constructor",

  cn = "childNodes",

  pn = "parentNode",

  ce = arguments.callee;

  if(pt.test(typeof a) || pt.test(typeof b) || a === null || b === null){

  return a === b || (isNaN(a) && isNaN(b)); //为了方便,此处假定NaN == NaN

  }

  if(a[cr] !== b[cr]){

  return false;

  }

  switch(a[cr]){

  case Date : {

  return a.valueOf() === b.valueOf();

  };

  case Function : {

  return a.toString().replace(fn,'$1') === b.toString().replace(fn,'$1'); //硬编码中声明函数的方式会影响到toString的结果,因此用正则进行格式化

  };

  case Array : {

  if(a.length !== b.length){

  return false;

  }

  for(var i=0;i<a.length;i++){

  if(!ce(a[i],b[i])){

  return false;

  }

  }

  break;

  };

  default : {

  var alen = 0, blen = 0, d;

  if(a === b){

  return true;

  }

  if(a[cn] || a[pn] || b[cn] || b[pn]){

  return a === b;

  }

  for(d in a){

  alen++ ;

  }

  for(d in b){

  blen++;

  }

  if(alen !== blen){

  return false;

  }

  for(d in a){

  if(!ce(a[d],b[d])){

  return false;

  }

  }

  break;

  };

  }

  return true;

  }

  console.log(compare({},{a:1})); //false

  console.log(compare({a:1},{b:2})); //false

  console.log(compare({b:2,a:1},{a:1,b:2})); //true

  console.log(compare({a:function(){return false;},b:2},{a:function(){return false;},b:2})); //true

  console.log(compare([],[])); //true

  console.log(compare([2,1],[1,2])); //false

  console.log(compare(function(){alert(1)},function(){})); //false

  console.log(compare(function aaa(){alert(1)},function(){alert(1)})); //true

  console.log(compare(document.getElementsByTagName("a")[0],document.getElementsByTagName("a")[1])); //false

  console.log(compare(document.getElementsByTagName("a")[0],document.getElementsByTagName("a")[0])); //true