将数字转换为字符串的“最佳”方法是什么(在速度优势、清晰度优势、内存优势等方面)?
一些例子:
String(n) n.toString() ""+n n+""
像这样:
var foo = 45;
var bar = '' + foo;
实际上,即使为了简单起见,我通常会这样做,但 1000 多次迭代似乎 对于原始速度而言,.toString()
是有优势的
在这里查看性能测试(不是我做的,而是我自己写的时候发现的):http://jsben.ch/#/ghQYR
根据上面的 JSPerf 测试最快:str = num.toString();
应该注意的是,当您考虑到它可以在 0.1 秒内以任何方式进行 100 万次转换时,速度上的差异并不太显着。
更新:速度似乎因浏览器而异。在 Chrome 中 num + ''
似乎是基于此测试最快的 http://jsben.ch/#/ghQYR
更新 2: 再次基于我上面的测试,应该注意到 Firefox 20.0.1 执行 .toString()
的速度比 '' + num
示例慢大约 100 倍。
在我看来,n.toString()
因其清晰而获奖,而且我认为它不会带来任何额外的开销。
null
、undefined
)几乎不会使其“不安全”。
null
或 undefined
的回答,不抛出错误不是在处理它,隐藏它也会导致“代码失败”。我不欣赏您的居高临下的陈述,例如“也许是时候少写代码,多读书了”,我建议您不要将 ad hominem 排除在您的论点之外,并且这次会很高兴地忽略它。
'' + undefined
会给你 'undefined'
这在我看来几乎没有更好,如果不是更糟,因为它默默地失败了。与 ('' + null) === 'null'
相同
对于语言新手来说,显式转换非常清楚。正如其他人所建议的那样,如果开发人员不了解强制规则,则使用类型强制会导致歧义。最终,开发人员的时间比 CPU 时间更昂贵,所以我会以后者为代价来优化前者。话虽这么说,在这种情况下,差异可能可以忽略不计,但如果不是,我确信有一些不错的 JavaScript 压缩器可以优化这类事情。
因此,出于上述原因,我会选择:n.toString()
或 String(n)
。 String(n)
可能是更好的选择,因为如果 n
为 null 或未定义,它不会失败。
null
或 undefined
。如果由于我的程序中的错误而导致 n
是 null
或 undefined
,那么我希望我的程序在这种状态下失败,以便让我有更好的机会找到并修复错误。程序崩溃是给程序员的礼物,可以帮助她找到错误:-)。另一种方法是交付不按设计工作的软件,仔细掩盖错误。所以,我不喜欢使用 String(n)
来掩盖错误。
String(n)
适合用于函数式样式,例如与下划线的组合 _.compose(funcThatNeedsAStringParam, String)
一起使用。
其他答案已经涵盖了其他选项,但我更喜欢这个:
s = `${n}`
简短,简洁,已经在许多其他地方使用(如果您使用的是现代框架/ ES 版本),因此可以肯定任何程序员都会理解它。
并不是说它(通常)很重要,但与 other methods 相比,它似乎也是 among the fastest。
n
是 undefined
它将通过使用 .toString()
引发语法错误
String(n)
相同的结果吗?唯一的区别是它不太清楚。
n
是 undefined
,则 `${n}`
返回字符串 'undefined'
。如果 n
是 undefined
或 null
,`${n || ''}`
会更好,它会返回一个空字符串。 注意:如果是 n = 0
,它也会返回一个 ''
。更复杂(也更慢)但返回 '0'
而不是空字符串:`${!isNaN(n) ? n : n || '' }`
...JavaScript 的解析器尝试将数字上的点符号解析为浮点文字。
2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first
以下是在 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在他的回答中给出)
显然是在开玩笑:
var harshNum = 108;
"".split.call(harshNum,"").join("");
或者在 ES6 中你可以简单地使用 template strings:
var harshNum = 108;
`${harshNum}`;
'' + number
方法更快。这就是说,这些基准测试的结果在多次执行时变化很大,因此不确定它们是否应该过于认真。
将任何变量转换为字符串的最简单方法是向该变量添加一个空字符串。
5.41 + '' // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'
(5.41 + '')
才能使用 .substring()
等字符串方法和其他方法
我使用 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%。
https://i.stack.imgur.com/mPxVd.png
如果您需要将结果格式化为特定的小数位数,例如表示货币,您需要类似 toFixed()
的方法。
number.toFixed( [digits] )
digits
是小数点后显示的位数。
我推荐 `${expression}`
,因为您不必担心错误。
[undefined,null,NaN,true,false,"2","",3].forEach(elem=>{ console.log(`${elem}`, typeof(`${elem}`)) }) /* 输出 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) }
当我有时间时,我将使用更多数据重新编辑它,因为现在这很好......
在 nodejs v8.11.2 中测试:2018/06/06
让我=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
对于几乎所有可能的现有和未来情况(输入为数字、null、未定义、符号、其他任何内容)的唯一有效解决方案是 String(x)
。不要使用 3 种方式进行简单操作,基于值类型假设,例如“这里我肯定将数字转换为字符串,这里肯定将布尔值转换为字符串”。
解释:
String(x)
处理空值、未定义、符号、[anything] 并为对象调用 .toString()
。
'' + x
在 x 上调用 .valueOf()
(强制转换为数字),在 Symbols 上抛出,可以提供依赖于实现的结果。
x.toString()
抛出空值和未定义。
注意:对于像 Object.create(null)
这样的无原型对象,String(x)
仍然会失败。
如果您不喜欢 '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));
}
对于数字文字,访问属性的点必须与小数点区分开来。如果您想在数字文字 123 上调用 String(),则可以使用以下选项:
123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()
"123"
的有益用例是什么?我什至没有在 OPs 问题中明确列出这种情况。根据经验:如果您现在是文字值,只需将其放在引号中,因为根本不需要处理。
我喜欢前两个,因为它们更容易阅读。我倾向于使用 String(n)
,但这只是风格问题。
那是除非你有一条线
var n = 5;
console.log ("the number is: " + n);
这是非常不言自明的
我认为这取决于情况,但无论如何您都可以使用 .toString()
方法,因为它很容易理解。
.toString() 是内置的类型转换函数,我不是这些细节的专家,但每当我们比较内置类型转换和显式方法时,总是首选内置的变通方法。
如果我必须考虑所有因素,我会建议以下
var myint = 1;
var mystring = myint + '';
/*or int to string*/
myint = myint + ''
恕我直言,这是转换为字符串的最快方法。如果我错了,请纠正我。
如果您想知道哪个是性能最高的,请查看我比较所有不同的 Number -> String 转换的地方。
看起来 2+''
或 2+""
是最快的。
https://jsperf.com/int-2-string
我们还可以使用 String 构造函数。根据 this benchmark,它是 Firefox 58 中将数字转换为字符串的最快方法,尽管它在流行的浏览器 Google Chrome 中比 " + num
慢。
方法toFixed()
也将解决目的。
var n = 8.434332;
n.toFixed(2) // 8.43
您可以调用 Number
对象,然后调用 toString()
。
Number.call(null, n).toString()
您可以将此技巧用于另一个 javascript 本机对象。
最近刚碰到这个,方法3和4都不合适,因为字符串是如何复制然后放在一起的。对于一个小程序来说,这个问题是微不足道的,但对于任何真正的 Web 应用程序来说,我们必须处理频率字符串操作的这个动作会影响性能和可读性。
使用 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
每次我运行它的时间都差不多。
不定期副业成功案例分享
'' + 123e-50
返回"1.23e-48"
。null foo
不会引发错误。