將value值轉換爲字符串方法以及原理詳解

這三種將value轉換爲字符串的方法是:
1. value.toString()
2. “” + value
3. String(value)

第一種方法不推薦
因爲null和undefined去調用toString方法會報錯
第二種和第三種方法的效果基本一樣

  • “” + value這種方法熟悉使用的人很容易理解,而且方便,但是它的可讀性是很差的,不利於代碼的維護。
  • String(value):這種方法可讀性更好,唯一的問題是,這種函數調用可能會迷惑人。因爲String同時也是一個構造函數,但是它作爲普通函數和作爲構造函數時的表現完全不同。
String('abc') === new String('abc');
> false

typeof String('abc');
> 'string'

typeof new String('abc');
> 'object'

String('abc') instanceof String;
> false

new String('abc') instanceof String;
> true

String作爲一個普通函數會產生一個字符串(原始值)
String作爲一個構造函數時會產生一個String對象的實例

“”+value 和 String(value)的細微差別

這兩種方法都是使用引擎內部的ToString()操作將原始值轉換爲字符串。
“內部操作”的意思是:這個操作函數是在ECMAScript5.1中定義的,但是ES語言本身並不能訪問到它,下面的表格解釋了ToString()是如何轉換原始值的。

將原始值轉換爲字符串

參數 結果
undefined “undefined”
null “null”
布爾值 “true”或”false”
數字 數字作爲字符串
字符串 無需轉換

將對象轉換爲字符串

這兩種方法都將對象值先轉化爲原始值,然後再將原始值轉化爲字符串。
但是在這個過程之中
+使用的是內部的ToPrimitive(Number)操作(除非被轉化的對象是date對象),
而String()用的是ToPrimitive(String)

  • ToPrimitive(Number):將一個對象轉換爲原始值,首先調用obj.valueOf()。如果返回值是一個原始值,則返回這個原始值,如果不是,再調用obj.toString()。如果返回的值是原始值,則返回這樣原始值,否則,拋出TypeError異常。
  • ToPrimitive(String):和上面的方法類似,只是先調用obj.toString()方法。

通過案例查看

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

通常結果總相同

上面講的區別,在實際情況中幾乎不太可能遇到,因爲:大部分的對象都使用了默認的valueOf()方法,返回的值總是這個對象本身。

> var x = {}
> x.valueoOf() === x
true

因此,ToPrimitive(Number)通常會跳過valueOf方法返回toString()方法的返回值,這就表現的和ToPrimitive(String)完全一樣,但是,如果這個對象是Boolean,Number或者String的對象實例,那麼它的valueOf()會返回一個原始值(被這個對象包裝前的原始值),那麼這兩種操作就會按照如下步驟執行:
- ToPrimitive(Number)返回了對象的valueOf()方法的返回值(被包裝前的原始值)再經過ToString()操作後的結果
- ToPrimitive(String)返回了對象的toString()方法的返回值(在該對象被包裝前的原始值上進行ToString()操作的返回值)。

就這樣,他們還是返回了相同的結果,只是轉換的途徑不同。

結論

你應該選擇哪種方式來將其他類型的值轉換爲字符串呢?
如果你能確保這個值永遠不會是null或者undefined,則可以用value.toString()來轉換,否則,”“+value和String(value)選擇哪一個都可以,看個人喜好,個人認爲String(value)更明確一點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章