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

Pac*_*ier 479 javascript string performance coding-style numbers

什么是将数字转换为字符串的"最佳"方式(在速度优势,清晰度优势,内存优势等方面)?

一些例子:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

scu*_*ffe 485

像这样:

var foo = 45;
var bar = '' + foo;
Run Code Online (Sandbox Code Playgroud)

实际上,即使我通常这样做是为了简单方便,但是对于原始速度来说,超过1,000次的迭代看起来有一个优点..toString()

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

最快的基于上面的JSPerf测试: str = num.toString();

应该注意的是,当您考虑到它可以在0.1秒内以任何方式进行1百万次转换时,速度差异并不过分显着.

更新:浏览器的速度似乎有很大差异.在http://jsben.ch/#/ghQYRnum + ''这个测试中,Chrome 似乎是最快的

更新2:再次基于我上面的测试,应该注意Firefox 20.0.1执行的.toString()速度比'' + num样本慢大约100倍.

  • 有些情况下,转换可能不会返回一个更好的答案:`''+ 123e-50`返回"1.23e-48". (51认同)
  • @hongymagic:答案实际上是唯一可以想到的:数字不关心也不知道它是如何输入的,标准的印刷表示在点之前只有一位数. (20认同)
  • 我在http://jsben.ch/ghQYR中运行测试,每次它显示不同的结果! (4认同)
  • 我喜欢这个答案,因为 `null foo` 不会引发错误。 (2认同)
  • @MaryamSaeidi:在上面使用** drublic **的_jsperf.com_测试似乎更加一致。 (2认同)

Car*_*osZ 336

在我看来n.toString(),因为它的清晰度而获奖,我认为它不会带来额外的开销.

  • @david.pfx `'' + undefined` 会给你 `'undefined'` 在我看来这几乎没有什么更好的,如果不是更糟的话,因为它默默地失败了。与 `('' + null) === 'null'` 相同 (14认同)
  • @ david.pfx这个问题询问如何将数值转换为字符串.提供不适用于此答案的非数字值(例如"null","undefined")的示例几乎不会使其"不安全". (12认同)
  • @david.pfx 有什么确定性?我的观点是,对于“null”或“undefined”没有答案,不抛出错误就不能处理它,隐藏它也会导致“代码失败”。我不欣赏你居高临下的说法,比如“也许是时候少写代码,多阅读”,我建议你不要在你的论点中进行人身攻击,并且这次会很乐意忽略它。 (5认同)
  • 这是不安全的。n可以为null或未定义。 (4认同)
  • @ MichaelMartin-Smucker:如果您写了很多JS,您就会意识到事情很少那么干。这个问题是开放的,并且IMO一个好的答案至少应该承认一个实际上为null或未定义的字符串的问题。YMMV。 (2认同)
  • @david.pfx我写了很多js,我不记得上次我需要一个数字作为字符串是什么时候,除了数字作为字符串之外的任何东西都足够了。这是正确的答案。处理“null”或“undefined”没有答案,因为它是特定于应用程序的,而我想“(n || defaultNumber).toString()”是大多数人在这种情况下想要的,我强烈不同意我们应该这样做将其应用于所有问题。这是关于将数字转换为字符串、良好的架构和其他需要的类型转换是单独的课程。 (2认同)
  • 这个 `n?.toString()` 会解决上述问题吗? (2认同)

Bry*_*yle 68

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

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

  • 问题是关于转换数字,而不是转换数字,或"null"或"undefined".如果由于我的程序中的错误,`n`是'null`或`undefined`,那么我更喜欢我的程序在这种状态下失败,让我有更好的机会找到并修复bug.程序崩溃是给程序员的礼物,帮助她找到错误:-).另一种方法是提供不按设计工作的软件,仔细掩盖错误.所以,我不喜欢使用`String(n)`来掩盖错误. (10认同)
  • `String(n)` 适合用于函数式风格,例如与下划线结合使用 `_.compose(funcThatNeedsAStringParam, String)`。 (2认同)
  • String(null)不会使程序崩溃,但是它将返回原义字符串“ null”,这可能不是您想要的。如果数据合法为空,那么您需要显式处理它。 (2认同)
  • @MattWallis 我认为这应该是开发人员的决定,而不是回答者的决定,你不觉得吗? (2认同)

Moh*_*rif 27

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

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

资源


Aru*_*hla 22

下面是在 JS 中将an 转换为Integerto的方法String

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

var num = 1
Run Code Online (Sandbox Code Playgroud)

方法一:

num = `${num}`
Run Code Online (Sandbox Code Playgroud)

方法二:

num = num + ''
Run Code Online (Sandbox Code Playgroud)

方法三:

num = String(num)
Run Code Online (Sandbox Code Playgroud)

方法四:

num = num.toString()
Run Code Online (Sandbox Code Playgroud)

注意:您不能直接拨打toString()号码。2.toString()会扔Uncaught SyntaxError: Invalid or unexpected token

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

  • 您可以使用“2..toString()”。注意双句点。 (4认同)

css*_*sek 16

舌头明显:

var harshNum = 108;
"".split.call(harshNum,"").join("");
Run Code Online (Sandbox Code Playgroud)

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

var harshNum = 108;
`${harshNum}`;
Run Code Online (Sandbox Code Playgroud)


sgo*_*les 12

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

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'
Run Code Online (Sandbox Code Playgroud)

  • 请注意,它必须位于parens内部:((5.41 +))要使用诸如.substring()和其他字符串方法 (2认同)

Car*_*ard 12

我推荐是`${expression}`因为你不需要担心错误。

[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
*/
Run Code Online (Sandbox Code Playgroud)


下面你可以测试一下速度。但顺序会影响结果。(在 StackOverflow 中)您可以在您的平台上测试它。

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)
}
Run Code Online (Sandbox Code Playgroud)


joh*_*odo 11

其他答案已涵盖其他选项,但我更喜欢这个:

s = `${n}`
Run Code Online (Sandbox Code Playgroud)

简短,简洁,已经在许多其他地方使用过(如果你使用的是现代框架/ ES版本),那么任何程序员都能理解它是安全的.

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

  • 这不是在所有情况下都会给出与“String(n)”相同的结果吗?唯一的区别是它不太清楚。 (2认同)
  • 而且慢得多。 (2认同)

Dar*_*zer 10

当我有时间的时候,我会用更多的数据重新编辑这个,因为现在这很好......

在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")
Run Code Online (Sandbox Code Playgroud)

输出

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
Run Code Online (Sandbox Code Playgroud)

  • 是的 - test4 是我经常使用的!! (2认同)

Eri*_*ick 10

我使用https://jsperf.com为以下案例创建了一个测试用例:

number + ''
`${number}`
String(number)
number.toString()
Run Code Online (Sandbox Code Playgroud)

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

截至 2018 年 7 月 24 日,结果表明这number + ''是 Chrome 中最快的,在与模板字符串文字相关的 Firefox 中。

两者String(number),并且number.toString()比最快的选项慢95%左右。

性能测试,如上描述


Tim*_*Tim 6

如果您需要将结果格式化为特定数量的小数位,例如表示货币,则需要类似toFixed()方法的内容.

number.toFixed( [digits] )
Run Code Online (Sandbox Code Playgroud)

digits 是小数位后显示的位数.

  • 不安全,除非您*知道*这是一个数字。 (2认同)