admin管理员组

文章数量:1410674

I am wondering why the following works:

oldversion = "1.3.52";
newversion = "1.3.54";

if (newversion > oldversion) {
    console.log('test');
}

but this does not:

if (1.3.54 > 1.3.52) {
    console.log('test');
}

I know that the last example won't work because they are not actual numbers. But I am trying to find out what JavaScript is doing when it encounters a string with a number in it.

This is what I found on W3Schools' JavaScript Comparison and Logical Operators page:

When paring a string with a number, JavaScript will convert the string to a number when doing the parison.

So how e it converts the string to a number and suddenly I am not getting an Uncaught SyntaxError: Unexpected number anymore?

I am wondering why the following works:

oldversion = "1.3.52";
newversion = "1.3.54";

if (newversion > oldversion) {
    console.log('test');
}

but this does not:

if (1.3.54 > 1.3.52) {
    console.log('test');
}

I know that the last example won't work because they are not actual numbers. But I am trying to find out what JavaScript is doing when it encounters a string with a number in it.

This is what I found on W3Schools' JavaScript Comparison and Logical Operators page:

When paring a string with a number, JavaScript will convert the string to a number when doing the parison.

So how e it converts the string to a number and suddenly I am not getting an Uncaught SyntaxError: Unexpected number anymore?

Share Improve this question edited Oct 22, 2018 at 7:22 Mathieu K. 2933 silver badges14 bronze badges asked Oct 6, 2016 at 12:08 Stephan-vStephan-v 20.4k32 gold badges124 silver badges211 bronze badges 10
  • 1 1.3.54 this is not a number, simple as that. 1 is a number or 1.3 is a number but adding further dots is invalid. – VLAZ Commented Oct 6, 2016 at 12:09
  • 1 It's just doing a string pare.. So using this for version checking would be wrong. – Keith Commented Oct 6, 2016 at 12:10
  • 1 "It works" for the strings you have tested. Try 1.23.5 vs 1.3.5 – deceze Commented Oct 6, 2016 at 12:14
  • 1 Last time I checked 12 was greater than 3 :) – Keith Commented Oct 6, 2016 at 12:26
  • 1 @Keith OP is getting confused about lexicographic parison the same way Javascript is… :D – deceze Commented Oct 6, 2016 at 12:27
 |  Show 5 more ments

4 Answers 4

Reset to default 4

You could use a function which iterates the segments.

function checkVersion(a, b) {
    var aa = a.split('.').map(Number),
        bb = b.split('.').map(Number),
        i,
        r = 0,
        l = Math.max(aa.length, bb.length);

    for (i = 0; !r && i < l; i++) {
        r = (aa[i] || 0) - (bb[i] || 0);
    }
    return r;
}

var oldversion = "1.3.52",
    newversion = "1.3.54";

if (checkVersion(newversion, oldversion) > 0) {
    console.log('test');
}

As mentioned in the ments, it's actually doing a string pare and not trying to turn anything into numbers.

You can verify this by trying:

var a = "a";
var b = "b";
console.log(a>b) // gives false

var a = "a";
var b = "b";
console.log(b>a) // gives true

As you say, when you pare a number and a string, the string gets transformed into a number. However, if the string contains an invalid number, the result will be NaN. This is funny due to the fact that:

NaN > 15 === false
NaN < 15 === false

So:

"1.3.52" > 1.4 === false
"1.3.52" < 1.4 === false

Obviously (and as you said in your post), paring 1.3.52 with 1.3.54 will throw an exception because they're not valid numbers.

Why "1.3.52" is interpreted bigger than '1.12.10'?

Strings are pared using Unicode code point order. For example, "Banana" es before "cherry". "9" is bigger than "80", but because "80" es before "9" in Unicode order. Thus, "1.3.52" is interpreted as bigger than '1.12.10'.

An easy way to find out order between strings and not getting tricked is using sort. For instance, ["1.3.52", "1.12.10", "1.11.0.0.0"].sort()

@Nina's solution should be the accepted answer, as it will be easier to understand I think. But anyway..

function versionGreaterEqual(newversion, oldversion) {
   var ov = oldversion.split('.').map(Number), //credit Nina :)
       nv = newversion.split('.').map(Number);
   return nv.reduce(function (a,b,i){
     return a+=b>=ov[i];
   },0)===nv.length;
}

console.log(versionGreaterEqual("1.3.54", "1.3.52")); //true
console.log(versionGreaterEqual("1.3.54", "1.13.52")); //false

本文标签: javascriptComparing 1352 and 1354 as strings and as numbersStack Overflow