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

Posted

技术标签:

【中文标题】在 JavaScript 中将数字转换为字符串的最佳方法是啥?【英文标题】:What's the best way to convert a number to a string in JavaScript?在 JavaScript 中将数字转换为字符串的最佳方法是什么? 【发布时间】:2011-08-11 13:05:38 【问题描述】:

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

一些例子:

    String(n)

    n.toString()

    ""+n

    n+""

【问题讨论】:

这个问题对我来说似乎很清楚。 【参考方案1】:

像这样:

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

实际上,尽管我通常这样做是为了简单方便,但经过 1,000 多次迭代后,对于原始速度而言,.toString()

具有优势

在这里查看性能测试(不是我写的,而是我自己写的时候发现的): http://jsben.ch/#/ghQYR

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

应该注意,当您考虑到它可以以任何方式在 0.1 秒内完成 100 万次时,速度上的差异并不过分显着。。 p>

更新:速度似乎因浏览器而异。在 Chrome 中num + '' 似乎是基于此测试最快的http://jsben.ch/#/ghQYR

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

【讨论】:

在某些情况下,转换可能不会返回更好的答案:'' + 123e-50 返回"1.23e-48" @hongymagic:这个答案实际上是唯一可以想象的:这个数字不关心也不知道它是如何输入的,标准的印刷表示是在点前正好有一个数字。 我在jsben.ch/ghQYR 进行了测试,每次都显示不同的结果! 我喜欢这个答案,因为null foo 不会引发错误。 @MaryamSaeidi:上面使用 drublicjsperf.com 测试似乎更加一致。【参考方案2】:

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

【讨论】:

这是不安全的。 n 可能为 null 或未定义。 @david.pfx 问题询问如何将数值转换为字符串。提供不适用于此答案的非数字值示例(例如nullundefined)几乎不会使其“不安全”。 @MichaelMartin-Smucker:如果你写了很多 JS,你就会意识到事情很少如此简单。这个问题是开放的,IMO 一个好的答案至少应该承认实际上为空或未定义的字符串的问题。 YMMV。 @david.pfx 有什么把握?我的意思是nullundefined 没有答案,不抛出错误不是处理它,隐藏它也会导致“代码失败”。我不欣赏您的居高临下的陈述,例如“也许是时候少写代码,多看书了”,我建议您不要将 ad hominem 排除在您的论点之外,这一次会很高兴地忽略它。 @david.pfx '' + undefined 会给你'undefined' 在我看来这几乎没有任何改善,如果不是更糟,因为它会默默地失败。与('' + null) === 'null' 相同【参考方案3】:

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

除非你有一行

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

这很不言自明

【讨论】:

【参考方案4】:

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

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

【讨论】:

请注意,它需要在括号内:(5.41 + '') 才能使用 .substring() 等 String 方法 为什么需要注意?【参考方案5】:

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

【讨论】:

【参考方案6】:

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

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

【讨论】:

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

如果我必须考虑一切,我会建议关注

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

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

【讨论】:

【参考方案8】:

如果您需要将结果格式化为特定的小数位数,例如表示货币,您需要类似toFixed() 方法。 p>

number.toFixed( [digits] )

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

【讨论】:

不安全,除非你知道这是一个数字。【参考方案9】:

显然是在开玩笑:

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

或者在 ES6 中你可以简单地使用 template strings:

var harshNum = 108;
`$harshNum`;

【讨论】:

如果我使用 ES6 模板运行基准测试,它有时甚至被证明比 '' + number 方法更快。也就是说,这些基准测试的结果在多次执行时会有很大差异,因此不确定是否应该把它们看得太严重。【参考方案10】:

...JavaScript 的解析器尝试解析 数字上的点表示法作为浮点文字。

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

Source

【讨论】:

【参考方案11】:

如果您想知道哪个性能最高,请查看我比较所有不同数字 -> 字符串转换的地方。

看起来2+''2+"" 是最快的。

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

【讨论】:

【参考方案12】:

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

【讨论】:

【参考方案13】:

方法toFixed()也能达到目的。

var n = 8.434332;
n.toFixed(2)  // 8.43

【讨论】:

【参考方案14】:

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

s = `$n`

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

并不是说它(通常)很重要,但与 other methods 相比,它似乎也是 among the fastest。

【讨论】:

如果 n 可能不是数字也是安全的。 @amn 如果nundefined,使用.toString() 会抛出语法错误 这不是在所有情况下都给出与String(n) 相同的结果吗?唯一的区别是它不太清楚。 而且慢得多。 如果nundefined`$n` 返回字符串'undefined'。如果nundefinednull,则`$n || ''` 会更好。 注意:如果n = 0,它也会返回''。更复杂(更慢)但返回 '0' 而不是空字符串:`$!isNaN(n) ? n : n || '' `【参考方案15】:

你可以调用Number对象,然后调用toString()

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

您可以将此技巧用于其他 javascript 原生对象。

【讨论】:

【参考方案16】:

最近才遇到这个,方法3和4都不合适,因为字符串是如何复制然后放在一起的。对于一个小程序,这个问题是微不足道的,但对于任何真正的 Web 应用程序,我们必须处理频率字符串操作的这个动作会影响性能和可读性。

Here is the link the read。

【讨论】:

【参考方案17】:

我将在有时间的时候用更多数据重新编辑它,现在这很好......

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

输出

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 是我经常使用的!!【参考方案18】:

使用 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

每次我运行它的时间都差不多。

【讨论】:

【参考方案19】:

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

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

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

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

String(number)number.toString() 都比最快的选项慢 95% 左右。

【讨论】:

【参考方案20】:

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

解释:

String(x) 处理空值、未定义、符号、[任何东西] 并为对象调用 .toString()

'' + x 在 x 上调用 .valueOf()(强制转换为数字),在 Symbols 上抛出,可以提供依赖于实现的结果。

x.toString() 抛出空值和未定义。

注意: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));

【讨论】:

【参考方案21】:

.toString() 是内置的类型转换函数,我不是这些细节方面的专家,但每当我们比较内置类型转换和显式方法时,总是首选内置的变通方法。

【讨论】:

【参考方案22】:

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

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

【讨论】:

看到这是可能的,基本上很有趣。但除此之外,进行这种转换而不是一开始就写"123" 有什么好处呢?我什至没有在 OPs 问题中明确列出这种情况。根据经验:如果您现在是文字值,只需将其放在引号中,因为根本不需要处理。【参考方案23】:

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

方法按性能降序排列。

var num = 1

方法一:

num = `$num`

方法二:

num = num + ''

方法三:

num = String(num)

方法四:

num = num.toString()

注意:您不能直接在号码上拨打toString()2.toString() 将抛出 Uncaught SyntaxError: Invalid or unexpected token

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

【讨论】:

【参考方案24】:

我推荐`$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
*/

您可以在下面测试速度。但顺序会影响结果。 (在 *** 中)您可以在您的平台上对其进行测试。

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)

【讨论】:

以上是关于在 JavaScript 中将数字转换为字符串的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

javascript 如何在Javascript中将字符串转换为数字?

如何在JavaScript中将数字的二进制表示从字符串转换为整数?

JavaScript中将字符串类型转换为整形的函数

在序列化中将长数字转换为字符串

如何在 JavaScript 中将字符串转换为浮点数?

在r中将多个列从字符转换为数字格式