Start.dev
Back to blog

How to convert a string to a number in JavaScript

Number(), parseInt() and parseFloat() each handle text differently. See which to use, what they do with tricky input, and how to check the result.

Ariel Weinberger
Ariel Weinberger ยท 6 min read

Why does "5" + 1 give you "51", and what's the right way to turn text into a number in JavaScript?

Short answer: use Number(text) when the whole string should be a number, and parseInt(text, 10) or parseFloat(text) when the number is at the start of other text, like "42px". Then check the result with Number.isNaN() or Number.isFinite(), because a failed conversion doesn't throw an error. It quietly gives you NaN.

By the end of this post you will know which method to pick, what each one does with tricky input like "", "3.9" and "1,000", and how to write a small function that converts safely. If variables and types are still new, start with What Is A Data Type (opens in a new tab) and Numbers (opens in a new tab).

Why you have a string in the first place

A lot of values arrive as text, even when they look like numbers:

  • the .value of a form input
  • the answer from prompt()
  • URL query parameters
  • anything you read back from localStorage

JavaScript won't always warn you. + joins strings, so "5" + 1 is "51". Other math operators convert quietly, so "5" - 1 is 4 and "5" * "2" is 10. That mix is exactly why it pays to convert once, on purpose, as soon as the value arrives.

Number(): the whole string must be a number

Number() reads the entire string. Spaces at the ends are fine. Anything else that isn't part of a number gives NaN, which stands for "not a number".

Number("42")     // 42
Number(" 42 ")   // 42
Number("3.9")    // 3.9
Number("1e3")    // 1000
Number("42px")   // NaN
Number("1,000")  // NaN
Number("")       // 0  (watch out)

That last line catches people. An empty string, or one with only spaces, becomes 0, not NaN. If an empty form field shouldn't count as zero, check for it before you convert.

The unary plus, +text, does exactly the same thing as Number(text). It's shorter, but Number() is easier to spot when you read the code later.

parseInt() and parseFloat(): read the number at the start

parseInt() and parseFloat() read from the left and stop at the first character that doesn't belong. They're the right tool when the number comes with something after it.

parseInt("42px", 10)    // 42
parseInt("3.9", 10)     // 3   (drops the decimal part)
parseFloat("3.9")       // 3.9
parseFloat("1e3")       // 1000
parseInt("1e3", 10)     // 1   (stops at "e")
parseInt("1,000", 10)   // 1   (stops at the comma)
parseInt("", 10)        // NaN

Always pass 10 as the second argument to parseInt(). It's the radix, the number base. Without it, parseInt("0x1A") reads the text as hexadecimal and returns 26, which is rarely what a form field meant.

Which one should you use?

InputNumber()parseInt(s, 10)parseFloat()
"42"424242
"3.9"3.933.9
"42px"NaN4242
"1,000"NaN11
""0NaNNaN
  • The whole value should be a number (a price, a quantity, an age): use Number(). Rejecting "42px" is a feature, not a bug.
  • The number comes with a unit ("42px", "12rem"): use parseFloat(), or parseInt(s, 10) if you only want the whole part.
  • Text with thousands separators like "1,000": none of them handle it. Remove the commas first, then convert.

Type Conversion (opens in a new tab) practices these exact cases.

Check the result before you use it

A failed conversion gives NaN, and NaN is sneaky. It isn't equal to anything, including itself, so value === NaN is always false. Use Number.isNaN(value) instead. Or, stricter, Number.isFinite(value), which is false for NaN and also for Infinity.

Here's a small function that turns text into a number, or null if it can't:

function toNumber(text) {
  const trimmed = text.trim();
  if (trimmed === "") return null;
  const value = Number(trimmed);
  return Number.isFinite(value) ? value : null;
}
 
toNumber("42")    // 42
toNumber(" 7 ")   // 7
toNumber("")      // null, not 0
toNumber("42px")  // null

Checking for an empty string first fixes the Number("") === 0 surprise. null makes the failure obvious to the code that calls it, so it can show a message instead of quietly doing math with NaN.

Avoid the older global isNaN(). It converts its argument first, so isNaN("abc") is true even though "abc" is a string, not NaN. Number.isNaN() doesn't do that.

Converting a whole array

To convert a list of strings, pass Number straight to map():

["1", "2", "3"].map(Number)    // [1, 2, 3]
["1", "2", "3"].map(parseInt)  // [1, NaN, NaN]

The second line is a classic trap. map() calls the function with the item and its index, so parseInt receives the index as its radix: parseInt("2", 1) and parseInt("3", 2) are both NaN. If you need parseInt, wrap it: .map((s) => parseInt(s, 10)). Our guide to JavaScript array methods covers map() in more depth.

Whole numbers and rounding

If you need a whole number from a decimal, choose on purpose:

  • Math.trunc(3.9) is 3, and Math.trunc(-3.9) is -3. It drops the decimal part.
  • Math.floor(-3.9) is -4. It always rounds down.
  • Math.round(3.5) is 4.

To check whether a value is already whole, use Number.isInteger(value). And remember that toFixed() goes the other way: (3.14159).toFixed(2) gives the string "3.14", which is for display, not for more math. Numbers And Math (opens in a new tab) covers these methods.

Common mistakes

  • Doing math with the raw string. price + tax joins two strings when price came from an input. Convert once, as soon as the value arrives.
  • Checking with === NaN. It's always false. Use Number.isNaN() or Number.isFinite().
  • Treating an empty field as zero. Number("") is 0. Check for a blank value before you convert.
  • Leaving out the radix. Write parseInt(text, 10) every time.
  • Using parseInt to validate. parseInt("42abc", 10) happily returns 42. If extra characters should be an error, use Number().

Quick recap

  • Values from inputs, prompts and URLs are strings until you convert them.
  • Number() converts the whole string, and gives NaN if any of it isn't a number.
  • parseInt(text, 10) and parseFloat(text) read the number at the start.
  • Number("") is 0, so check for blanks first.
  • Check results with Number.isNaN() or Number.isFinite(), never === NaN.

Frequently asked questions

What's the best way to convert a string to a number in JavaScript?

For most cases, Number(text). It converts the whole string and fails clearly with NaN when the text isn't a number. Use parseFloat() or parseInt(text, 10) only when the number is followed by other text, like a unit.

What's the difference between parseInt and Number?

Number() needs the whole string to be a number. parseInt() reads from the start and stops at the first character that doesn't fit, and it drops anything after a decimal point. So Number("42px") is NaN, but parseInt("42px", 10) is 42.

Why do I get NaN?

The text contained something that couldn't be read as a number, like a letter, a comma, or a currency sign. Log the original string to see exactly what you received, then clean it up before converting.

Why does "5" + 1 equal "51"?

When one side of + is a string, JavaScript joins the two values as text. Convert first: Number("5") + 1 is 6.

Practice

Try it in your browser, with nothing to install: Type Conversion (opens in a new tab), then Numbers And Math (opens in a new tab), then put it to work in the Project Tip Calculator (opens in a new tab) project.

Where to go next

Type conversion sits early in JavaScript Basics (opens in a new tab), right after variables and data types. If you're learning JavaScript for a job, JavaScript interview questions for junior developers covers related questions, like when to use == and when to use ===.

Level up your coding skills

Jump into interactive courses and start building real-world projects.

Start learning

Related posts

Learn the JavaScript array methods you will use daily: map, filter, find, some, every, reduce and sort, with runnable examples on one shopping cart.
Ariel Weinberger
Ariel Weinberger ยท 5 min read
Ten JavaScript interview questions junior developers get asked, with short answers, runnable examples, and the follow-ups interviewers like to ask next.
Ariel Weinberger
Ariel Weinberger ยท 5 min read
You can read JavaScript but keep forgetting how to write it. The difference between an expression and a statement explains most of the syntax.
Ariel Weinberger
Ariel Weinberger ยท 11 min read