譯者注:前兩天在看ES5的時候順便出了一道題,今天看到這篇文章,剛好解釋的很清楚,就翻譯了一下.
在JavaScript中,主要有三種方法能讓任意值轉換為字串.本文講解了每種方法以及各自的優缺點.
1.轉換字串的三種方法
這三種將value轉換為字串的方法是:
1.value.toString()
2."" + value
3.String(value)
第一種方法存在的問題是,它不能把null和undefined轉換為字串.還有第二種和第三種方法,這兩種方法的效果基本一樣.
•""+value: 使用加法運算子配合一個Null 字元串可以把任意值轉換為字串,我覺得這種方法代碼的可讀性很差,但相對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(obj)
toString
valueOf
TypeError: Cannot 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 [怎樣才能更好的串連多個字串]