译者注:前两天在看ES5的时候顺便出了一道题,今天看到这篇文章,刚好解释的很清楚,就翻译了一下.
在JavaScript中,主要有三种方法能让任意值转换为字符串.本文讲解了每种方法以及各自的优缺点.
1.转换字符串的三种方法
这三种将value转换为字符串的方法是:
1.value.toString()
2."" + value
3.String(value)
第一种方法存在的问题是,它不能把null和undefined转换为字符串.还有第二种和第三种方法,这两种方法的效果基本一样.
•""+value: 使用加法运算符配合一个空字符串可以把任意值转换为字符串,我觉得这种方法代码的可读性很差,但相对String(value)来,还是有一些人更喜欢用这种转换方式.
•String(value): 这种方法可读性更好,唯一的问题是,这种函数调用可能会迷惑一些人,尤其是那些熟悉Java的的程序员,因为String同时也是一个构造函数.要注意的是它作为普通函数和作为构造函数时的表现完全不同:
> String("abc") === new String("abc")
false
> typeof String("abc")
'string'
> String("abc") instanceof String
false
> typeof new String("abc")
'object'
> new String("abc") instanceof String
true
String作为普通函数时会产生一个字符串(一个原始值).作为构造函数时会产生一个String对象的实例.后者在JavaScript中很少用到,所以基本上你可以忽略掉String作为构造函数的用法,但一定要记得它是个转换函数.
2.""+value 和 String(value)的细微差别
到现在你已经知道了+ 和 String()都可以将它们的“参数”转换为字符串.但他们的转换方式还是着有细微的差别,不过几乎所有的情况下,转换结果都是一样的.
2.1 将原始值转换为字符串
这两种方法都是使用引擎内部的ToString()操作将原始值转换为字符串的.“内部操作”的意思是:这个操作函数是在ECMAScript 5.1 (§9.8)中定义的,但ES语言本身并不能访问到它.下面这个表格解释了ToString()是如何转换原始值的.
参数 |
结果 |
undefined |
"undefined" |
null |
"null" |
布尔值 |
"true"或者"false"
|
数字 |
数字作为字符串,比如"1.765"
|
字符串 |
无需转换 |
2.2 將物件值轉換為字串 這兩種方法都先將物件值轉換為原始值,然後再將原始值轉換為字串.但是在這個轉換中, 使用的是內部的ToPrimitive(Number)操作(除非被轉換的是date物件),而String()用的是ToPrimitive(String).
•ToPrimitive(Number): 將一個物件值轉換為原始值,先呼叫obj.valueOf().如果傳回值是一個原始值,則傳回這個原始值.如果不是,則再呼叫obj.toString().如果傳回值是個原始值,傳回這個原始值.否則,拋出TypeError異常.
•ToPrimitive(String): 和上面的方法類似,只是優先調用obj.toString()方法而不是obj.valueOf().
透過轉換下面的這個對象,你可以看到它們之間的差異:
var obj = {
valueOf: function () {
console.log("valueOf");
return {}; // 不是原始值,繼續執行
},
toString: function () {
console.log("toString");
return {}; // 不是原始值,繼續執行
}
};
//執行:
> "" obj
valueOf
toString
TypeError: Cannot convert object to primitive value
> String(object to primitive value
> String(obj)
toString to convert object to primitive value
2.3 結果通常都相同 上面講的區別,在實際情況中幾乎不太可能遇到.因為:大部分對像都使用了預設的繼承而來的valueOf()方法,傳回值總是這個物件本身.
> var x = {}
> x.valueOf() === x
true
因此, ToPrimitive (Number)通常會跳過valueOf方法回傳toString()方法的回傳值,這就表現的和ToPrimitive(String)完全一樣.但是,如果這個物件是Boolean,Number或String的物件實例,那麼它的valueOf( )會傳回一個原始值(被這個物件包裝前的原始值).那麼這兩種操作就會按照以下步驟執行:
•ToPrimitive(Number)傳回了物件的valueOf()方法的傳回值(被包裝前的原始值)再經過ToString()操作後的結果.
•ToPrimitive(String)傳回了物件的toString()方法的回傳值(在該物件被包裝前的原始值上進行ToString()操作的回傳值).
就這樣,他們還是回傳了相同的結果,只是轉換的途徑不同.
3.結論 你應該選擇哪種方式來將其他類型的值轉換為字串呢?如果你能確保這個值永遠不會是null或者undefined,則可以用value.toString()來轉換.否則,"" value和String (value)選哪個都可以,看個人喜好,我認為String(value) 比較明確一點.
4.相關文章
-
JavaScript values: not everything is an object [原始值和物件值的區別]
-
What is {} {} in JavaScript? [解釋了 運算子的工作原理]
-
String concatenation in JavaScript [怎樣才能更好的連接多個字串]