750

What's the "best" way to convert a number to a string (in terms of speed advantage, clarity advantage, memory advantage, etc) ?

Some examples:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Pacerier
  • 86,231
  • 106
  • 366
  • 634

25 Answers25

735

like this:

var foo = 45;
var bar = '' + foo;

Actually, even though I typically do it like this for simple convenience, over 1,000s of iterations it appears for raw speed there is an advantage for .toString()

See Performance tests here (not by me, but found when I went to write my own): http://jsben.ch/#/ghQYR

Fastest based on the JSPerf test above: str = num.toString();

It should be noted that the difference in speed is not overly significant when you consider that it can do the conversion any way 1 Million times in 0.1 seconds.

Update: The speed seems to differ greatly by browser. In Chrome num + '' seems to be fastest based on this test http://jsben.ch/#/ghQYR

Update 2: Again based on my test above it should be noted that Firefox 20.0.1 executes the .toString() about 100 times slower than the '' + num sample.

EscapeNetscape
  • 2,892
  • 1
  • 33
  • 32
scunliffe
  • 62,582
  • 25
  • 126
  • 161
  • 79
    There are cases where the conversion may not return a preferable answer: `'' + 123e-50` returns `"1.23e-48"`. – hongymagic Oct 30 '13 at 06:35
  • 1
    This answer does not seem to be true anymore if you look at http://jsperf.com/number-to-string/2. Might be worth updating it :) – drublic Apr 27 '15 at 07:21
  • 38
    @hongymagic: that answer is in fact the only conceivable: the number does not care nor know how it was entered, and the standard printed representation is with exactly one digit before the dot. – Svante Sep 02 '15 at 18:32
  • 5
    I ran the test in http://jsben.ch/ghQYR, every time it shows me a different result! – Maryam Saeidi Aug 16 '17 at 12:39
  • 3
    I like this answer because a `null foo` doesn't throw an error. – ttugates Nov 17 '17 at 18:41
  • 2
    @MaryamSaeidi: Using **drublic**'s _jsperf.com_ test above seems more consistent. – Giraldi Apr 21 '18 at 09:38
  • jsperf is way better than jsben. jsben is pretty and it shows up in google results now, but it's useless for accuracy. – aamarks Oct 21 '19 at 02:48
  • Simply for exhaustivity you can also use JSON.stringify() which is almost as fast as .toString() – Ronan Quillevere Jan 17 '20 at 10:07
  • 1
    As an updated version of this answer, i've ran some test using the same benchmark as you, but in addition of ES6 string template. And turns out it's a close match ! ( https://jsben.ch/RkGXi ) This might be a more elegant way of converting number to string. – Nicolas May 12 '20 at 00:20
  • Please, note that if the number is -0 then the result will be 0 without the negative sign. – Mohammad Tbeishat Jan 03 '23 at 10:09
496

In my opinion n.toString() takes the prize for its clarity, and I don't think it carries any extra overhead.

Étienne
  • 4,773
  • 2
  • 33
  • 58
CarlosZ
  • 8,281
  • 1
  • 21
  • 16
  • It does carry some overhead even though it's insignificant in recent browser versions. In Firefox Quantum at least – Peter Chaula Feb 05 '18 at 06:45
  • 31
    This is unsafe. n might be null or undefined. – david.pfx Nov 13 '18 at 10:11
  • 93
    @david.pfx the question asks how to convert numeric values to a string. Providing examples of non-numeric values (e.g. `null`, `undefined`) that don't work with this answer hardly makes it "unsafe". – Michael Martin-Smucker Dec 02 '18 at 23:24
  • 10
    @MichaelMartin-Smucker: If you write a lot of JS you realise that things are rarely so cut and dried. The question was open and IMO a good answer should at least acknowledge the issue of a string that is actually null or undefined. YMMV. – david.pfx Feb 19 '19 at 22:37
  • 2
    @david.pfx I have written a LOT of js and I do not remember the last time where I needed a number as a string and anything but a number as a string would have sufficed. This is the correct answer. There is no answer to handling `null` or `undefined` as it is application specific, whilst I imagine `(n || defaultNumber).toString() ` is what most people would want in such a situation I strongly disagree we should be working it into all questions. This was about converting numbers to strings, good architecture and other type conversions where needed are separate lessons. – George Reith Apr 23 '20 at 12:41
  • 14
    @david.pfx what certainty? my point was there is no answer to `null` or `undefined`, not throwing an error isn't handling it and hiding it will also cause "code to fail". I don't appreciate your condescending statements like "perhaps it's time to write less code and read more", I advise you to keep ad hominem out of your argument and will happily look past it this time. – George Reith Apr 27 '20 at 09:40
  • 12
    @david.pfx `'' + undefined` will give you `'undefined'` which is hardly any better in my opinion, if not worse as it fails silently. The same with `('' + null) === 'null'` – Maciej Krawczyk Apr 24 '21 at 06:47
  • @MaciejKrawczyk: Better by what metric? A good answer should have been longer and considered the possibility of non-numeric. Whether or how to deal with non-numeric values will depend on context, and in some of those contexts `''+value` is better. YMMV. – david.pfx Apr 26 '21 at 01:38
  • 2
    would this `n?.toString()` address the above issues? – Riza Khan Jan 11 '22 at 23:39
114

Explicit conversions are very clear to someone that's new to the language. Using type coercion, as others have suggested, leads to ambiguity if a developer is not aware of the coercion rules. Ultimately developer time is more costly than CPU time, so I'd optimize for the former at the cost of the latter. That being said, in this case the difference is likely negligible, but if not I'm sure there are some decent JavaScript compressors that will optimize this sort of thing.

So, for the above reasons I'd go with: n.toString() or String(n). String(n) is probably a better choice because it won't fail if n is null or undefined.

Bryan Kyle
  • 13,361
  • 4
  • 40
  • 45
  • 22
    The question was about converting numbers, not about converting numbers, or `null`, or `undefined`. If `n` is `null` or `undefined` due to a bug in my program, then I'd prefer my program to fail in this state, to give me a better chance of finding and fixing the bug. Program crashes are gifts to the programmer, to help her find the bugs :-). The alternative is to deliver software that does not work as designed, having carefully glossed over the bugs. So, I'm not a fan of using `String(n)` to mask an error. – Matt Wallis Sep 22 '15 at 12:12
  • 2
    `String(n)` is good for using in a functional style, e.g. with underscore's combine `_.compose(funcThatNeedsAStringParam, String)`. – Rik Martins Apr 17 '17 at 14:21
  • 6
    String(null) won't crash the progam, but it will return the literal string "null", which is probably not what you want. If the data could legitimately be null, then you need to handle it explicitly. – Peter Smartt May 23 '17 at 01:35
  • 2
    @MattWallis I think that should be the decision of the developer, not the answerer, don't you think? – forresthopkinsa Dec 21 '18 at 17:48
50

The below are the methods to convert an Integer to String in JS.

The methods are arranged in the decreasing order of performance.

var num = 1

Method 1:

num = `${num}`

Method 2:

num = num + ''

Method 3:

num = String(num)

Method 4:

num = num.toString()

Note: You can't directly call toString() on a number. 2.toString() will throw Uncaught SyntaxError: Invalid or unexpected token.

(The performance test results are given by @DarckBlezzer in his answer)

Arun Joseph
  • 2,736
  • 25
  • 35
48

Other answers already covered other options, but I prefer this one:

s = `${n}`

Short, succinct, already used in many other places (if you're using a modern framework / ES version) so it's a safe bet any programmer will understand it.

Not that it (usually) matters much, but it also seems to be among the fastest compared to other methods.

johndodo
  • 17,247
  • 15
  • 96
  • 113
  • It's also safe if n might be not a number. – david.pfx Nov 13 '18 at 10:13
  • But so is `n.toString()` then, isn't it? – Armen Michaeli May 24 '19 at 13:21
  • 1
    @amn if `n` is `undefined` it will throw a syntax error by using `.toString()` – Jee Mok Nov 08 '19 at 00:18
  • 2
    Doesn't this just give the same result as `String(n)` in all cases? The only difference is that it's less clear. – Bennett McElwee Nov 19 '19 at 00:03
  • 2
    And much slower. – Adrian Bartholomew Jan 07 '20 at 03:04
  • 1
    If `n` is `undefined`, `\`${n}\`` returns string `'undefined'`. Better would be `\`${n || ''}\`` which returns an empty string if `n` is `undefined` or `null`. **Attention**: it also returns an `''` if `n = 0`. More complex (and slower) but returning `'0'` instead of an empty string: `\`${!isNaN(n) ? n : n || '' }\`` – phse Jul 10 '20 at 11:25
  • 1
    @AdrianBartholomew - Just out of interest, why do you say it is much slower? Apparently, it is much faster, or the fastest, according to [these results](https://stackoverflow.com/a/50730371/4424636) - see the results for test 4. – Greenonline Sep 22 '21 at 04:02
40

...JavaScript's parser tries to parse the dot notation on a number as a floating point literal.

2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first

Source

Abhishek Pandey
  • 13,302
  • 8
  • 38
  • 68
Mohammad Arif
  • 6,987
  • 4
  • 40
  • 42
21

Tongue-in-cheek obviously:

var harshNum = 108;
"".split.call(harshNum,"").join("");

Or in ES6 you could simply use template strings:

var harshNum = 108;
`${harshNum}`;
cssimsek
  • 1,255
  • 14
  • 20
  • If I run the benchmarks with ES6 templates, it sometimes even proves to be faster than the `'' + number` method. This said, the results of these benchmarks varies a lot when performing them multiple times so not sure if they should be taken too serious. – Nico Van Belle Apr 20 '18 at 09:28
12

The simplest way to convert any variable to a string is to add an empty string to that variable.

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'
Saurabh Gokhale
  • 53,625
  • 36
  • 139
  • 164
11

I used https://jsperf.com to create a test case for the following cases:

number + ''
`${number}`
String(number)
number.toString()

https://jsperf.com/number-string-conversion-speed-comparison

As of 24th of July, 2018 the results say that number + '' is the fastest in Chrome, in Firefox that ties with template string literals.

Both String(number), and number.toString() are around 95% slower than the fastest option.

performance tests, description above

Erick
  • 2,488
  • 6
  • 29
  • 43
10

I recommended `${expression}` because you don't need to worry about errors.

[undefined,null,NaN,true,false,"2","",3].forEach(elem=>{
  console.log(`${elem}`, typeof(`${elem}`))
})

/* output
undefined string
null      string
NaN       string
true      string
false     string
2         string
          string
3         string
*/

Below you can test the speed. but the order will affect the result. (in StackOverflow) you can test it on your platform.

const testCases = [
  ["${n}", (n) => `${n}`], // 
  ['----', undefined],

  [`"" + n`, (n) => "" + n],
  [`'' + n`, (n) => '' + n],
  [`\`\` + n`, (n) => `` + n],
  [`n + ''`, (n) => n + ''],
  ['----', undefined],

  [`String(n)`, (n) =>  String(n)],
  ["${n}", (n) => `${n}`], // 

  ['----', undefined],
  [`(n).toString()`, (n) => (n).toString()],
  [`n.toString()`, (n) => n.toString()],

]

for (const [name, testFunc] of testCases) {
  if (testFunc === undefined) {
    console.log(name)
    continue
  }
  console.time(name)
  for (const n of [...Array(1000000).keys()]) {
    testFunc(n)
  }
  console.timeEnd(name)
}
Carson
  • 6,105
  • 2
  • 37
  • 45
9

If you need to format the result to a specific number of decimal places, for example to represent currency, you need something like the toFixed() method.

number.toFixed( [digits] )

digits is the number of digits to display after the decimal place.

Tim
  • 1,755
  • 2
  • 22
  • 34
9

I'm going to re-edit this with more data when I have time to, for right now this is fine...

Test in nodejs v8.11.2: 2018/06/06

let i=0;
    console.time("test1")
    for(;i<10000000;i=i+1){
     const string = "" + 1234;
    }
    console.timeEnd("test1")
    
    i=0;
    console.time("test1.1")
    for(;i<10000000;i=i+1){
     const string = '' + 1234;
    }
    console.timeEnd("test1.1")
    
    i=0;
    console.time("test1.2")
    for(;i<10000000;i=i+1){
     const string = `` + 1234;
    }
    console.timeEnd("test1.2")
    
    i=0;
    console.time("test1.3")
    for(;i<10000000;i=i+1){
     const string = 1234 +  '';
    }
    console.timeEnd("test1.3")
    
    
    i=0;
    console.time("test2")
    for(;i<10000000;i=i+1){
     const string = (1234).toString();
    }
    console.timeEnd("test2")
    
    
    i=0;
    console.time("test3")
    for(;i<10000000;i=i+1){
     const string = String(1234);
    }
    console.timeEnd("test3")
    
    
    i=0;
    console.time("test4")
    for(;i<10000000;i=i+1){
     const string = `${1234}`;
    }
    console.timeEnd("test4")
    
    i=0;
    console.time("test5")
    for(;i<10000000;i=i+1){
     const string = 1234..toString();
    }
    console.timeEnd("test5")
    
    i=0;
    console.time("test6")
    for(;i<10000000;i=i+1){
     const string = 1234 .toString();
    }
    console.timeEnd("test6")

output

test1: 72.268ms
test1.1: 61.086ms
test1.2: 66.854ms
test1.3: 63.698ms
test2: 207.912ms
test3: 81.987ms
test4: 59.752ms
test5: 213.136ms
test6: 204.869ms
DarckBlezzer
  • 4,578
  • 1
  • 41
  • 51
4

The only valid solution for almost all possible existing and future cases (input is number, null, undefined, Symbol, anything else) is String(x). Do not use 3 ways for simple operation, basing on value type assumptions, like "here I convert definitely number to string and here definitely boolean to string".

Explanation:

String(x) handles nulls, undefined, Symbols, [anything] and calls .toString() for objects.

'' + x calls .valueOf() on x (casting to number), throws on Symbols, can provide implementation dependent results.

x.toString() throws on nulls and undefined.

Note: String(x) will still fail on prototype-less objects like Object.create(null).

If you don't like strings like 'Hello, undefined' or want to support prototype-less objects, use the following type conversion function:

/**
 * Safely casts any value to string. Null and undefined are converted to ''.
 * @param  {*} value
 * @return {string}
 */
function string (str) {
  return value == null ? '' : (typeof value === 'object' && !value.toString ? '[object]' : String(value));
}
Alexander Shostak
  • 673
  • 10
  • 11
4

With number literals, the dot for accessing a property must be distinguished from the decimal dot. This leaves you with the following options if you want to invoke to String() on the number literal 123:

123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()
Mohit Dabas
  • 2,333
  • 1
  • 18
  • 12
  • Basically interesting to see this is possible. But apart from that, what's a beneficial use case for doing this conversion rather than just writing `"123"` in the first place? I don't even see this case explicitly listed in OPs question. As a rule of thumb: if you now the literal value, just put it in quotes for there is no processing required at all. – Thomas Urban Sep 08 '20 at 09:49
2

.toString() is the built-in typecasting function, I'm no expert to that details but whenever we compare built-in type casting verse explicit methodologies, built-in workarounds always preferred.

Mubeen Khan
  • 997
  • 1
  • 10
  • 11
2

I like the first two since they're easier to read. I tend to use String(n) but it is just a matter of style than anything else.

That is unless you have a line as

var n = 5;
console.log ("the number is: " + n);

which is very self explanatory

Aleadam
  • 40,203
  • 9
  • 86
  • 108
2

I think it depends on the situation but anyway you can use the .toString() method as it is very clear to understand.

Bubletan
  • 3,833
  • 6
  • 25
  • 33
Sergey K
  • 4,071
  • 2
  • 23
  • 34
1

Method toFixed() will also solves the purpose.

var n = 8.434332;
n.toFixed(2)  // 8.43
António Almeida
  • 9,620
  • 8
  • 59
  • 66
Shaik Md N Rasool
  • 484
  • 1
  • 5
  • 13
1

If I had to take everything into consideration, I will suggest following

var myint = 1;
var mystring = myint + '';
/*or int to string*/
myint = myint + ''

IMHO, its the fastest way to convert to string. Correct me if I am wrong.

Kumar
  • 5,038
  • 7
  • 39
  • 51
0

If you are curious as to which is the most performant check this out where I compare all the different Number -> String conversions.

Looks like 2+'' or 2+"" are the fastest.

https://jsperf.com/int-2-string

Alex Cory
  • 10,635
  • 10
  • 52
  • 62
0

We can also use the String constructor. According to this benchmark it's the fastest way to convert a Number to String in Firefox 58 even though it's slower than " + num in the popular browser Google Chrome.

Peter Chaula
  • 3,456
  • 2
  • 28
  • 32
0

You can call Number object and then call toString().

Number.call(null, n).toString()

You may use this trick for another javascript native objects.

IKavanagh
  • 6,089
  • 11
  • 42
  • 47
ufadiz
  • 1
  • 1
0

Just come across this recently, method 3 and 4 are not appropriate because how the strings are copied and then put together. For a small program this problem is insignificant, but for any real web application this action where we have to deal with frequency string manipulations can affects the performance and readability.

Here is the link the read.

roger
  • 1,225
  • 2
  • 17
  • 33
0

It seems similar results when using node.js. I ran this script:

let bar;
let foo = ["45","foo"];

console.time('string concat testing');
for (let i = 0; i < 10000000; i++) {
    bar = "" + foo;
}
console.timeEnd('string concat testing');


console.time("string obj testing");
for (let i = 0; i < 10000000; i++) {
    bar = String(foo);
}
console.timeEnd("string obj testing");

console.time("string both");
for (let i = 0; i < 10000000; i++) {
    bar = "" + foo + "";
}
console.timeEnd("string both");

and got the following results:

❯ node testing.js
string concat testing: 2802.542ms
string obj testing: 3374.530ms
string both: 2660.023ms

Similar times each time I ran it.

Shahaed
  • 379
  • 3
  • 14
0

Just use template literal syntax:

`${this.num}`
kelsny
  • 23,009
  • 3
  • 19
  • 48