由app版本高低判断延伸到javascript字符串比较

170 阅读1分钟

最近在参与部门的app 重构,其中有一个是根据后台版本配置与当前 app 版本的表来提示用户是否有新版本,需要更新的提示。然后发现旧的代码直接使用的字符串比较:

const v1 = '1.0.1';
const v2 = '1.0.2';
console.log(v1 > v2); // false

乍一看,好像没问什么问题。但是当出现下面版本时,问题就来了:

const v1 = '1.2.1';
const v2 = '1.12.1';
console.log(v1 > v2); // true

其实这就涉及到了字符串的比较规则,字符串比较是使用基于标准字典的 Unicode 值来进行比较的。

'2' > '1' // true
'abc' > 'acb' // false
// 数字比较
2 > 11 // false
// 字符串比较
'2' > '11' // true

之所以出现 '2' > '11' 为真的情况,字符串比较的情况下会逐个字符进行比较。

'2'.charCodeAt(0) // 50
'11'.charCodeAt(0)  // 49

这样比较,就会出现 '2' > '11' 为 true的情况。

回归到最初的问题,那么 app 版本比较的思路就有了。

补位方法:

既然字符串比较是逐位进行比较的,那么我们就假定主副补丁版本的最高位数为4,不足四位的左侧补齐0。

function toNum(version) {
  const versionArr = version.split('.');
  const num_place = ['0000', '000', '00', '0', ''];
  const len = versionArr.length;
  for (let i = 0; i < len; i++) {
    const itemLen = versionArr[i].length;
    versionArr[i] = num_place[itemLen] + versionArr[i];
  }
  const res = versionArr.join('');
  return res;
};

function compareVersion(a, b) {
  const version_a = toNum(a);
  const version_b = toNum(b);
  console.log(version_a);
  return version_a > version_b;
}


console.log(compareVersion('1.0.1', '1.1.2')); // false
console.log(compareVersion('0.0.1', '0.0.2')); // false
console.log(compareVersion('1.1.0', '1.2.0')); // false
console.log(compareVersion('1.2.1', '1.12.1')); // false
console.log(compareVersion('1.1.12', '1.2')); // false

数值比较

分别对 主,副,补丁版本的数值进行比较:

function compareVersion(v1, v2) {
  const v1arr = v1.split('.');
  const v2arr = v2.split('.');
  const len1 = v1arr.length;
  const len2 = v2arr.length;
  const max = len1 > len2 ? len1 : len2;
  let i = 0;
  for(; i < max; i++) {
    const v1v = v1arr[i] ? parseInt(v1arr[i]) : 0;
    const v2v = v2arr[i] ? parseInt(v2arr[i]) : 0;
    if (v2v > v1v) {
      return false;
    }
  }
  if (v1arr.join() === v2arr.join()) {
    return false;
  }
  return true;
}

console.log(compareVersion('1.0.1', '1.1.2')); // false
console.log(compareVersion('0.0.1', '0.0.2')); // false
console.log(compareVersion('1.1.0', '1.2.0')); // false
console.log(compareVersion('1.2.1', '1.12.1')); // false
console.log(compareVersion('1.1.12', '1.2')); // false