在JavaScript中转换为字符串


184

我发现了三种String在JavaScript中将变量转换为的方法。
我在jQuery源代码中搜索了这三个选项,它们都在使用中
我想知道它们之间是否有任何区别:

value.toString()
String(value)
value + ""

演示

它们都产生相同的输出,但是其中一个比另一个更好吗?
我会说的+ ""优点是可以节省一些字符,但这不是那么大的优势,还有其他吗?


1
在我看来,如果所有事物都平等,那么标准toString()就是要走的路。
asawyer 2012年

1
@asawyer。那为什么呢?如果它们都产生相同的输出并执行相同的输出,则选择一个并继续输出。我的看法是否确实如此
gdoron支持Monica 2012年

1
前两个方法应该等效(您应检查标准,但构造函数将调用toString)。第三个通常会产生相同的输出,但是它涉及的机制却非常不同(除了速度方面涉及不同的调用,因此可能不是您对每种对象的期望)。
阿德里亚诺·雷佩蒂

6
我认为,toString从语义上讲,这是自我记录您试图获取与对象等效的字符串这一事实的最清晰方法。String(...)有点钝,value + ""有点乱。toString如果您认为有必要,还可以使用自定义实现覆盖默认值,这是次要的好处。
asawyer 2012年

2
@Adriano。但是+ ""根据jsperf来看,它是最快的,所以...我猜它可以通过其他方式实现它。
gdoron支持Monica 2012年

Answers:


212

value是时,它们的行为确实有所不同null

  • null.toString()引发错误- 无法调用null的方法'toString'
  • String(null)返回- “ null”
  • null + ""也返回- “ null”

如果value是,则会发生非常相似的行为undefined(请参阅jbabey的答案)。

除此之外,性能差异可以忽略不计,除非您在大循环中使用它们,否则不必担心。


这实际上是一个有趣的差异。因此,toString()当您尚未检查时,应避免使用null
Sammy S.

@SammyS。不知道打印nullundefined到屏幕是否是更理想的行为,然后是JavaScript错误...
Justus Romijn 2014年

@JustusRomijn:确实如此。同时,我开始使用Option类型来处理此类错误。
Sammy S.

您可以使用typeof检查所有这些强制转换的变量以检查字符串。typeof(null +'')=='字符串'
Bruce Lim 2014年

4
还有另一种情况,他们的行为有所不同。v + ''如果v同时具有toString()和valueOf()方法,则返回错误的结果。串联将忽略toString()并将使用valueOf()。一类的例子为哪些级联失败:github.com/processing-js/processing-js/blob/...
Mikita Belahlazau

26

有差异,但可能与您的问题无关。例如,toString原型不存在于未定义的变量上,但是您可以使用其他两种方法将undefined转换为字符串:

var foo;

var myString1 = String(foo); // "undefined" as a string

var myString2 = foo + ''; // "undefined" as a string

var myString3 = foo.toString(); // throws an exception

http://jsfiddle.net/f8YwA/


3
如果根本没有定义变量,则仍然会出现错误String()。示例:String(test);throws Uncaught ReferenceError: test is not defined,而var test; String(test);会导致"undefined"
安东尼

17

它们的行为相同,但toString也提供了一种转换数字二进制,八进制或十六进制字符串的方法:

例:

var a = (50274).toString(16)  // "c462"
var b = (76).toString(8)      // "114"
var c = (7623).toString(36)   // "5vr"
var d = (100).toString(2)     // "1100100"

9

根据此JSPerf测试,它们的速度有所不同。但是除非您要大量使用它们,否则它们中的任何一个都应该表现良好。

为了完整性:正如asawyer所述,您也可以使用.toString()方法。


2
这jsperf具有相同的测试两次,我编辑它new String()返回的对象不是一个String
gdoron是支持莫妮卡

new String()返回对象是。String()但是,返回的字符串是问题中的那个。
康奈尔2012年

2
这并非完全正确。从结果中可以看出,将一个空字符串和一个对象串联起来不会产生与将一个对象和一个空字符串串联在一起的结果。此外,new String(blarg)为您提供了String可以调用的对象toString()。在我的Chrome调试器中,除了上述区别外,它们有效地产生了相同类型的对象。
Sammy S.

@SammyS。您能否在示例中添加性能结果示例?jsperf链接目前已关闭,并且肯定会在未来5年以上的时间内再次出现。
mxmlnkn16年

9

除上述所有内容外,还应注意,对于定义的值v

  • String(v) 来电 v.toString()
  • '' + vv.valueOf()在任何其他类型强制转换之前进行调用

因此,我们可以执行以下操作:

var mixin = {
  valueOf:  function () { return false },
  toString: function () { return 'true' }
};
mixin === false;  // false
mixin == false;    // true
'' + mixin;       // "false"
String(mixin)     // "true"

在FF 34.0和Node 0.10中测试



4

实际示例:我有一个日志函数,可以使用任意数量的参数调用log("foo is {} and bar is {}", param1, param2)。如果将DEBUG标志设置为true,则括号将替换为给定的参数,并将字符串传递给console.log(msg)。参数可以并且将是Strings,Numbers以及JSON / AJAX调用可能返回的任何参数,甚至是null

  • arguments[i].toString()由于可能的null值,因此不是一个选择(请参阅Connell Watkins答案)
  • JSLint会抱怨arguments[i] + ""。这可能会或可能不会影响使用什么的决定。有些人严格遵守JSLint。
  • 在某些浏览器中,连接空字符串比使用字符串函数或字符串构造函数要快一些(请参阅Sammys S. answer中的JSPerf测试)。在Opera 12和Firefox 19中,串联空字符串的速度更快(在Firefox 19中为95%),或者至少JSPerf这么说。

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.