js的比较其实一直没搞太明白, 这里总结一下

字符串的比较
var string1 = "World";
var string2 = "World";
var result = string1.localeCompare(string2); //如果相等result为0
string1 == string2; // 这个会自动做类型转化, 所以很多时候结果会比较奇怪.
string1 === string2; // 这个同时保证类型和内容都相等.
stringx.trim() //如果要去除空格等空白字符的影响, 先用trim处理下字符串.
A1.slice(0, -1) //这个是硬生生删除尾部一个字符, 这是怎么想的啊, 思路太清奇了, 现实中永远不要用这种思路处理字符串.
str1 < str2 ? -1 : +(str1 > str2) //可以这样比较字符串, 

简单的说就是string和int没啥区别, 在js的范畴中这个可以随意比较的.

数组
var a1 = [1,2,3];
var a2 = [1,2,3];
a1==a2;    //  false
JSON.stringify(a1)==JSON.stringify(a2);    //  true 这个方法会比较慢.
ary1.join('') == ary2.join('')//这个本质上和上面类似, 都是把array转化为string.
array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]}) //纯数组, 数组的元素不能有对象.
array1.length === array2.length && array1.every((value, index) => value === array2[index]) //同上
array1.length === array2.length && array1.sort().every(function(value, index) { return value === array2.sort()[index]}); //排序后比较, 也就是说忽略数组本身的顺序.

var i = a.length;
if (i != b.length) return false;
while (i--) { //这个i--很妙啊. 但是能比较a[0]吗? 结论是keyi, i--返回的是i
  if (a[i] !== b[i]) return false;
}
return true;
//foreach, in, every, reduce, ..., filter都可以

对于数组而言, 最重要的一点就是, 对象形成的数组, 比如:

let a=[
  {a:1,b:2}, {b:2},{b:2,c:3}
]
let b=[
  {b:2,a:1}, {b:2},{c:3,b:2}
]
怎么判断他们其实是相等的呢?

如果array包含对象, 那么问题就复杂了, 就要按照对象比较的方法来比较对象,

对象
  • js规定对象如果用=去比较, 那么比较的是他们的ref地址. 这个基本没啥用了.
  • 如果我比较的两个对象, 那么肯定是比较键值对, 同一个键是否同值, 因此键的顺序无关紧要.
x = {a: 1, b: 2};
y = {b: 2, a: 1};
JSON.stringify(x)==JSON.stringify(y);    //  false, 不止结果不对, 而且还比较慢.
Object.toJSON(x) == Object.toJSON(y);  //typeerror, object没这个属性.
JSON.encode(x)===JSON.encode(y); //这个也会报错, 需要使用json库

(function compare2Objects(x, y) {
  for (p in x) { // in 来逐个比较. 不严谨的代码
    if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) return false;
    return typeof x[p] === 'object' ? compare2Objects(x[p], y[p]) :  x[p] === y[p];
  }
})(x, y); //

//https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects 这里面atmin的答案: 
(function deepEqual(x, y) {
  const ok = Object.keys, tx = typeof x, ty = typeof y;
  return x && y && tx === 'object' && tx === ty ? (
    ok(x).length === ok(y).length &&
    ok(x).every(key => deepEqual(x[key], y[key]))
  ) : (x === y);
})(x, y);  //true, 这个是true!!!!!!
//还有一个思路使用deep copy, 把两个对象都往一个地方copy, 这样保证相同的顺序, 然后再比较.


很多迷思
  1. 数组当然要保证顺序了, 他们的实际情况是: {1:a, 2:b, 3:c}, 他的key就是顺序, 因此数组的判断当然要保证顺序的判断.
  2. 数组是对象的数组这个情况当然要考虑, 怎么可能都是基础类型的数组来判断呢? 接口中的数组十个有十个是对象数组啊.
  3. 对象当然是判断键值对了, 不可能要求键值对的顺序还一致.
  4. 对象肯定不要求prototype一致, 以js的风格, 长得一样的就是一样的.
  5. 对象的方法是否要判断, 需要具体问题具体分析, 一般的接口校验, 并不需要.
  6. 键值对做包含关系的判断, 肯定也是需要的, 谁家还不扩展个接口啊.
//样例代码
杭锋推荐
  • https://lodash.com