在JavaScript中将数字转换为字符串的最佳方法是什么?


Answers:


516

像这样:

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

实际上,尽管我通常这样做是为了简单方便,但对于原始速度而言,似乎出现了1000多次迭代,但对于.toString()

请参阅此处的性能测试(不是我自己的,而是在我自己编写时发现的):http : //jsben.ch/#/ghQYR

根据上述JSPerf测试最快: str = num.toString();

应该注意的是,当您认为速度差异可以在0.1秒内进行1百万次转换时,速度差异并不是太大。

更新:速度因浏览器而异。在Chrome中num + '',根据此测试,看来速度最快http://jsben.ch/#/ghQYR

更新2:再次根据我上面的测试,应该注意到Firefox 20.0.1的执行.toString()速度比'' + num示例慢约100倍。


58
在有些情况下转换可能不会返回一个最好的回答情况:'' + 123e-50回报"1.23e-48"
hongymagic

21
@hongymagic:答案实际上是唯一可以想到的:该数字不关心也不知道它是如何输入的,并且标准的打印表示形式是在点之前精确地一位。
Svante

4
每次显示不同的结果时,我都在jsben.ch/ghQYR中运行了该测试!
Maryam Saeidi '17

2
我喜欢这个答案,因为a null foo不会引发错误。
ttugates

2
@MaryamSaeidi:在上面使用drublicjsperf.com测试似乎更加一致。
Giraldi

364

我认为n.toString()该奖项以其清晰为目的,我认为它不会带来任何额外的开销。


即使在最近的浏览器版本中它并不重要,它也确实会带来一些开销。至少在Firefox Quantum中
peterchaula

11
这是不安全的。n可以为null或未定义。
david.pfx

20
@ david.pfx问题询问如何将数值转换为字符串。提供非数值的例子(如nullundefined)没有这个答案几乎工作,使得“不安全”。
Michael Martin-Smucker '18

5
@ MichaelMartin-Smucker:如果您写了很多JS,您就会意识到事情很少这么干。这个问题是开放的,IMO的一个很好的答案至少应该承认一个实际上为null或未定义的字符串的问题。YMMV。
david.pfx

@ david.pfx我写了很多js,我不记得上一次我需要一个数字作为字符串,而除了数字以外的任何东西都足够了。这是正确的答案。对于处理没有任何答案,null或者undefined它是针对特定应用的,尽管我想这(n || defaultNumber).toString() 是大多数人在这种情况下想要的,但我强烈不同意我们应该将其应用于所有问题。这是关于将数字转换为字符串,良好的体系结构以及其他需要进行单独的课程的类型转换。
George Reith

73

对于该语言的新手来说,显式转换非常明显。正如其他人所建议的那样,如果开发人员不了解强制规则,则使用类型强制会导致歧义。最终,开发人员的时间要比CPU时间花费更多,因此我会以后者为代价对前者进行优化。话虽这么说,这种情况下的差异可能微不足道,但是如果不是这样的话,我敢肯定有一些不错的JavaScript压缩器可以优化这种情况。

因此,出于上述原因,我建议使用:n.toString()String(n)String(n)可能是一个更好的选择,因为如果n为null或未定义,它不会失败。


12
问题在于转换数字,而不是转换数字或nullundefined。如果nnullundefined由于我的程序中的错误引起的,那么我希望我的程序在这种状态下失败,以便给我一个更好的机会来发现并修复该错误。程序崩溃是给程序员的礼物,可以帮助她发现错误:-)。另一种选择是交付经过精心掩盖的错误后无法正常工作的软件。因此,我不喜欢String(n)掩盖错误。
马特·沃利斯

1
String(n)非常适合用于功能性样式,例如带下划线的Combine _.compose(funcThatNeedsAStringParam, String)
里克·马丁斯

2
String(null)不会使程序崩溃,但是它将返回原义字符串“ null”,这可能不是您想要的。如果数据合法为空,那么您需要显式处理它。
彼得·斯马特

1
@MattWallis我认为这应该是开发人员的决定,而不是回答者的决定,您认为吗?
forresthopkinsa

30

... JavaScript的解析器尝试将数字上的点符号解析为浮点文字。

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

资源


17

舌头很明显:

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

或者在ES6中,您可以简单地使用 模板字符串

var harshNum = 108;
`${harshNum}`;

如果我使用ES6模板运行基准测试,有时甚至证明比该'' + number方法更快。这就是说,这些基准测试的结果在多次执行时会有很大差异,因此不确定是否应该将它们视为过于严肃的测试。
Nico Van Belle

15

其他答案已经涵盖了其他选项,但我更喜欢以下选项:

s = `${n}`

简短,简洁,已经在其他许多地方使用(如果您使用的是现代框架/ ES版本),因此可以肯定,任何程序员都可以理解。

并不是说它通常很重要,但是与其他方法相比,它似乎也是最快的方法之一


如果n可以不是数字,则也是安全的。
david.pfx

但是n.toString(),是吗?
AMN

1
@amn如果nundefined,它将通过使用.toString()
Jee Mok

难道不只是String(n)在所有情况下都能得到相同的结果吗?唯一的区别是不清楚。
Bennett McElwee

而且慢得多。
阿德里安·巴塞洛缪

12

将任何变量转换为字符串的最简单方法是向该变量添加一个空字符串。

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'

2
请注意,它必须位于parens内:(5.41 + '')要使用String方法.substring()和其他方法一样
-Gjaa

为什么需要注意这一点?
阿德里安·巴塞洛缪


6

如果需要将结果格式设置为特定的小数位数(例如代表货币),则需要类似toFixed()方法的方法。

number.toFixed( [digits] )

digits 是小数点后显示的位数。


2
不安全,除非您知道这是一个数字。
david.pfx

2

我喜欢前两个,因为它们更易于阅读。我倾向于使用String(n)但这仅是样式问题。

那就是除非你有一行

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

这是很自我解释的


2

我认为这取决于情况,但是无论如何您都可以使用该.toString()方法,因为它很容易理解。


2

.toString()是内置的类型转换函数,我对此并不熟练,但是每当我们比较内置类型转换和显式方法时,总是首选内置解决方法。


1

如果我不得不考虑所有因素,我建议您

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

恕我直言,它是最快的方式转换为字符串。如果我错了,请纠正我。


1

几乎所有可能的现有和将来情况(输入是数字,空值,未定义,符号等)的唯一有效解决方案是String(x)。不要基于值类型假设使用3种简单操作方法,例如“这里我将数字绝对转换为字符串,这里将布尔值绝对转换为字符串”。

说明:

String(x)处理null,未定义,符号,[任何内容]并调用.toString()对象。

'' + x 来电 .valueOf() x(广播到数字), Symbols可以提供与实现相关的结果。

x.toString() 引发null和未定义。

注意:String(x)在没有原型的对象上仍然会失败Object.create(null)

如果您不喜欢“ Hello,undefined”之类的字符串,或者不希望支持缺少原型的对象,请使用以下类型转换函数:

/**
 * 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));
}

1

对于数字文字,用于访问属性的点必须与小数点区分开。如果要在数字文字1​​23上调用String(),则可以使用以下选项:

123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()

1

以下是在JS中将Integer转换为String的方法

这些方法按性能的降序排列。

(性能测试结果由@DarckBlezzer在他的答案中给出)

var num = 1

方法1:

num =`$ {num}`

方法2:

num = num +''

方法3:

num =字符串(num)

方法4:

num = num.toString()

注意: 您不能直接从数字中调用tostring()

例如: 2.toString()将抛出未捕获的SyntaxError:无效或意外的令牌



0

我们还可以使用String构造函数。根据此基准,即使比 " + num流行的浏览器Google Chrome 慢,它也是在Firefox 58中将数字转换为字符串的最快方法。



0

您可以先调用Numberobject然后再调用toString()

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

您可以将此技巧用于其他javascript本机对象。


0

刚刚遇到这个问题,方法3和4不适合,因为如何复制字符串然后将它们放在一起。对于小型程序而言,此问题无关紧要,但是对于任何实际的Web应用程序,我们必须处理频率字符串操纵的此操作可能会影响性能和可读性。

这是读取的链接


0

如果有时间,我将使用更多数据重新编辑此文件,因为现在很好...

在Node.js 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")

输出

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

是的-test4是我经常使用的!
阿德里安·巴塞洛缪

0

使用node.js时,结果似乎相似。我运行了这个脚本:

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");

并得到以下结果:

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

每次我运行类似的时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.