What is the difference between parseint() and operator + before a string?

Asked

Viewed 455 times

11

I saw a colleague convert a string to integer using the syntax var a = +"10" but I always used the parseInt() and the line is usually like this var a = parseInt("10").

Why when placing the operator + before a string that happens? And what’s the best recommendation: use the parseInt() or the operator? Has some influence on performance?

  • 2

    The only advice I can give that is not in the answers is to use the 2nd parameter of parseInt to specify the basis of the conversion if by some chance or bad luck you have to support IE8-

4 answers

8


Javascript has weak typing, as well as dynamic typing. This means that it does type coercion to try to meet what the programmer had done using as close a criterion as possible, so if the code has an operator + even having only one string he thinks he wants a mathematical operation. I would only decide that he wants a concatenation if you had two strings.

Does this seem like a wrong decision and not very intuitive? Yes, so people don’t like JS, it’s a language that tries to help so much that it gets in the way. Weak typing is almost always a mistake.

What is the solution to this? Make your own as best as possible, avoid these corner cases. Just because it works doesn’t mean it should. Every programmer should know this. As long as someone thinks testing and working means you’re right there’ll be bad code out there.

When you want to convert a string for a number use the most correct function for this, and it is parseInt(). Give clarity that’s what you want, it’s not an accident.

You need to measure (in each browser, each version) to see if one gives more performance than another, but it doesn’t matter and should not give, at least anything significant because both will need to make a relatively complex algorithm to achieve the goal, none is miraculously simple and the other very complicated, in essence will do the same thing.

I’m in favor until language has a way Strict more rigid that can connect a limiter to this kind of thing and force it to use the right one. Better yet, make Typescript official because people are using JS to make systems, a weak and dynamic typing language no longer works.

JS Good Partes Vs Definitive Guide

  • Thank you Maniero, you have clarified my doubts!

  • 1

    That’s not corner case, that’s another operator.

6

The first syntax uses unary operator +, which converts the variable to Number.

How your question is about the difference using the function parseInt it will also convert to Number but will truncate any decimal house that this variable has for that variable to become a Number of type integer.

So if your goal is to turn a string into an integer number the function parseInt is safer, but if you just want to convert the string to Number the first syntax is more succinct.

Example:

var numero = "7.5"
console.log(+numero) // 7.5
console.log(parseInt(numero)) // 7

  • For decimal numbers there is the parseFloat(), just adding to your answer.

2

Complementing the other answers: when the string contains an integer (such as '123', '42', etc), there is no difference in the result. But when the string is not exactly an integer, the results may be different. For example:

['', '     ', '\n', '7.5', '1x', '1.2.3', '3e2', 'xyz'].forEach(s => {
    console.log(`+"${s}" = ${+s} - parseInt("${s}") = ${parseInt(s)}`);
});

Of those, only the string 'xyz' gives the same result for both cases. The others do not:

+"" = 0 - parseInt("") = NaN
+"     " = 0 - parseInt("     ") = NaN
+"
" = 0 - parseInt("
") = NaN
+"7.5" = 7.5 - parseInt("7.5") = 7
+"1x" = NaN - parseInt("1x") = 1
+"1.2.3" = NaN - parseInt("1.2.3") = 1
+"3e2" = 300 - parseInt("3e2") = 3
+"xyz" = NaN - parseInt("xyz") = NaN

For empty string, string containing multiple spaces and string containing line break (\n), the conversion with + returns zero, and parseInt returns NaN.

For a string that represents a float, + gives the same result as parseFloat and keeps the houses after the comma, returning 7.5. Already parseInt remove the decimal places and return 7.

To '1x', the + returns NaN, while parseInt returns 1. This is because according to the specification the unary operator +, when applied to strings, uses the algorithm described here (that basically does not recognize the character x and so fails and returns NaN). Already parseInt uses a different algorithm: it reads the digits and when it finds something that is not a valid digit, ignores the rest of the string and converts the digits it has read so far, and so the return is 1 (similar what PHP does). The same goes for '1.2.3', returning NaN with the operator +, but returns 1 with parseInt.

Already a number in scientific notation ('3e2') is correctly recognized by +, returning 300. But parseInt does not recognize this format and returns 3 (for the reason already described in the previous paragraph). In this case, you could use parseFloat('3e2'), returning 300.

Finally, for the string 'xyz', both return NaN.

Remember also that there are some bizarre situations that can occur if you pass numbers instead of strings to parseInt:

console.log(parseInt(0.0000005)); // 5
console.log(parseInt(1000000000000000000000)); // 1

// com o "+" isso não ocorre
// obs: os valores ficam corretos, mas a saída estará em notação científica
console.log(+0.0000005); // 5e-7
console.log(+1000000000000000000000); // 1e+21

Did you find it strange? The explanation is here.


In this reply from Soen has a very complete comparative table, with more cases and the respective results for each conversion. In this same link there are other responses that cite other differences and corner cases.

Testing done on Firefox 68.0.2 and Chrome 76.0.3809.132 (both for Windows 64-bit).

2

The type of data in an expression can confuse some script operations if the expected components of the operation are not of the right type. Javascript tries its best to perform internal conversions to avoid such problems, but it cannot read your mind. If your intentions differ from the way Javascript treats values, then you won’t get the results you expected.

A particularly interesting case is the sum of numbers that can be in the format of text strings. In a simple arithmetic statement, which sums two numbers, you get the expected result:

var soma = 3+3;

console.log(soma);

But if one of these numbers is string, Javascript will tend to convert the other value to a string - turning the sign action from arithmetic sum to string association (or concatenation). Therefore, in the instruction 3+"3" the force of the string at the second value prevails over the entire operation. The first value is automatically converted to string, and the result associates the two strings.

var soma = 3+"3";

console.log(soma);

See what happens when another number is added to the instruction: 3 + 3 + "3"

var soma = 3 + 3 + "3";

console.log(soma);

There is a logic behind this result. The expression is evaluated from left to right. The first operation of more works on two numbers, generating the value 6. But, when 6 is about to be added to "3", Javascript allows the force of the string "3" to predominate. 6 is converted to string and the two values are concatenated resulting in 63.

Note that in such cases the operator + before strings did not convert the string to integer!

If a numeric value is stored as a string, your scripts will have difficulties applying this value to a mathematical operation. Javascript offers two built-in functions to convert number string representations to true numbers: parsInt() and parseFloat().

CONCLUSION

the correct function to be used is parseInt()

var soma = 3 + 3 + parseInt("3");

console.log(soma);

  • But in that case, if you were to use the + to convert, it would not use: 3 + 3 + +"3"?

  • @fernandosavio, who will know if they know?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.