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

时间:2011-04-23 16:25:33

标签: javascript string performance coding-style numbers

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

一些例子:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

23 个答案:

答案 0 :(得分:447)

像这样:

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

实际上,即使我通常这样做是为了简单方便,超过1,000次的迭代显示原始速度,.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倍。

答案 1 :(得分:316)

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

答案 2 :(得分:59)

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

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

答案 3 :(得分:22)

  

... 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

答案 4 :(得分:15)

明显的舌头:

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

或者在ES6中,您只需使用template strings

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

答案 5 :(得分:11)

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

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

答案 6 :(得分:6)

如果您需要格式化结果为特定的小数位数,例如代表货币,则需要toFixed()方法。

number.toFixed( [digits] )

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

答案 7 :(得分:6)

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

s = `${n}`

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

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

答案 8 :(得分:2)

我认为这取决于具体情况,但无论如何你可以使用.toString()方法,因为它很清楚。

答案 9 :(得分:2)

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

除非你有一行

,否则就是这样
var n = 5;
console.log ("the number is: " + n);

这是非常自我解释

答案 10 :(得分:2)

我使用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%。

performance tests, description above

答案 11 :(得分:1)

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

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

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

答案 12 :(得分:1)

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

答案 13 :(得分:1)

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

说明:

String(x)处理null,undefined,Symbols,[anything]并为对象调用.toString()

'' + x在x上调用.valueOf()(向数字广播),引发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));
}

答案 14 :(得分:0)

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


您可以在下面测试速度。但顺序会影响结果。 (在 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)
}

答案 15 :(得分:0)

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

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

答案 16 :(得分: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

我每次都运行类似的时间。

答案 17 :(得分:0)

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

在nodejs v8.11.2:2018/06/06中测试

00:06 deploy:assets:precompile
  01 ~/.rvm/bin/rvm 2.4.4 do bundle exec rake assets:precompile
  01 rake aborted!
  01 ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:206:in `rescue in _decrypt'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:183:in `_decrypt'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:157:in `decrypt_and_verify'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/messages/rotator.rb:21:in `decrypt_and_verify'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_file.rb:79:in `decrypt'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_file.rb:42:in `read'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:21:in `read'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:33:in `config'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/encrypted_configuration.rb:38:in `options'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/core_ext/module/delegation.rb:271:in `method_missin…
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:433:in `secret_key_base'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:176:in `key_generator'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/globalid-0.4.1/lib/global_id/railtie.rb:26:in `block (2 levels) in <class:Railtie>'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:69:in `block in execute_hook'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:51:in `each'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application/finisher.rb:75:in `block in <module:Finisher>'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:32:in `instance_exec'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:32:in `run'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:61:in `block in run_initializers'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/initializable.rb:60:in `run_initializers'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:361:in `initialize!'
  01 /var/www/jrpescados/releases/20180606215329/config/environment.rb:5:in `<main>'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `block in req…
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/loaded_features_index.rb:65:in `register'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:20:in `require_with…
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/bootsnap-1.3.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:29:in `require'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `block in require'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:249:in `load_dependency'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/activesupport-5.2.0/lib/active_support/dependencies.rb:283:in `require'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:337:in `require_environment!'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/railties-5.2.0/lib/rails/application.rb:520:in `block in run_tasks_blocks'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/sprockets-rails-3.2.1/lib/sprockets/rails/task.rb:62:in `block (2 levels) in define'
  01 /var/www/jrpescados/shared/bundle/ruby/2.4.0/gems/rake-12.3.1/exe/rake:27:in `<top (required)>'
  01 /home/deploy/.rvm/rubies/ruby-2.4.4/bin/bundle:30:in `block in <main>'
  01 /home/deploy/.rvm/rubies/ruby-2.4.4/bin/bundle:22:in `<main>'
  01 /home/deploy/.rvm/gems/ruby-2.4.4/bin/ruby_executable_hooks:15:in `eval'
  01 /home/deploy/.rvm/gems/ruby-2.4.4/bin/ruby_executable_hooks:15:in `<main>'

输出

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

答案 18 :(得分:0)

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

Here is the link the read

答案 19 :(得分:0)

您可以拨打Number对象,然后拨打toString()

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

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

答案 20 :(得分:0)

方法toFixed()也将解决目的。

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

答案 21 :(得分:0)

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

答案 22 :(得分:0)

如果您对哪个性能最高的人感到好奇,请查看我在哪里比较所有不同的数字 - &gt;字符串转换。

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

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