+{ a: 1, toString: function() { return `10` }, valueOf: function() { return `100` } }
以上引申出物件資料的轉換的問題:
所有物件繼承了兩個轉換方法:
- toString(): 它的作用是返回一個反映這個物件的字串
- valueOf():它的作用是返回它相應的原始值
toString()
toString()
函式的作用是返回object的字串表示。JavaScript
中object預設的toString()
方法返回字串”[object Object]
“。定義類時可以實現新的toString()
方法,從而返回更加具有可讀性的結果。JavaScript
對於陣列物件、函式物件、正規表示式物件以及Date日期物件均定義了更加具有可讀性的toString()方法:
-
Array
的toString()
方法將返回以逗號分隔的陣列成員。
var arr = [1, 2, 3]
arr.toString() // "1,2,3"
-
Function
的toString()
方法將返回函式的文字定義。
var fun = function() { return `fun` }
fun.toString() // "function() { return `fun` }"
-
RegExp
的toString()
方法與Function
的toString()
方法類似,將返回正規表示式的文字定義。
var reg = /d+/g
reg.toString() // "/d+/g"
-
Date
的toString()
方法將返回一個具有可讀性的日期時間字串。
var date = new Date()
date.toString() // "Tue Feb 12 2019 14:04:36 GMT+0800 (中國標準時間)"
- 如果
Boolean
值是true
,則返回 “true”。否則,返回 “false”。
var boolean = true
boolean.toString() // "true"
valueOf()
valueOf()
函式的作用是返回該object自身。
與toString()
一樣,定義類時可以實現新的valueOf()
方法,從而返回需要的結果。JavaScript
對於Date
物件定義了更加具有可讀性的valueOf()
方法:
-
Date
的valueOf()
方法將返回一個時間戳數值,該數值為Date
物件與1970年1月1日零時的時間差(以毫秒為單位)。
var date = new Date()
date.valueOf() // 1549951476233
- 其他一律返回物件本身。
示例
var colors = ["red", "blue", "green"] // 建立一個包含3 個字串的陣列
alert(colors.toString()) // red,blue,green
alert(colors.valueOf()) // red,blue,green
alert(colors) // red,blue,green
三個輸出全部一樣,那麼toString()和valueOf()區別到底是什麼?看下一個我寫的例子:
var arr = [1,2,3]
alert(Array.isArray(arr.valueOf())) // true
alert(Array.isArray(arr.toString())) // false
結果是第一個是true
而第二個是false
,為什麼呢,其實valueOf()
呼叫完以後還是返回一個陣列。這個陣列被alert
的時候會呼叫toString()
函式,所以不是valueOf()
和toString()
函式相同,而是間接的呼叫了toString()
函式!
進一步測試下:
var arr = [1,2,3]
arr.toString = function () {
alert("呼叫了toString函式");
}
alert(arr.valueOf()) // "呼叫了toString函式"
結果就是我們會看到“呼叫了`toString函式”。
驗證如下程式碼:
var test = {
value: 10,
toString: function() {
console.log(`toString`)
return this.value
},
valueOf: function() {
console.log(`valueOf`)
return this.value
}
}
alert(test) // 10 toString
alert(+test) // 10 valueOf
alert(`` + test) // 10 valueOf
alert(String(test)) // 10 toString
alert(Number(test)) // 10 valueOf
alert(test == `10`) // true valueOf
alert(test === `10`) // false
valueOf
的意思是返回最適合該物件型別的原始值,而toString
則是將在該物件型別的原始值以字串形式返回。
示例1
alert(test) // 10 toString
這裡我們的alert
函式需要是的字串,所以獲取的是字串,而不是原始值,故而呼叫了toString
示例2
alert(+test) // 10 valueOf
同理,alert
要的是字串不是原始值,其實是(+test)的結果呼叫了toString
,而+test
被呼叫了valueOf
為了驗證我們這樣寫:
var test = {
value: 1,
valueOf: function () {
alert("呼叫了test的valueOf函式")
return this.value
},
toString: function () {
alert("呼叫了test的toString函式")
return this.value
}
};
var test2 = {
value: +test,
valueOf: function () {
alert("呼叫了test2的valueOf函式")
return this.value;
},
toString: function () {
alert("呼叫了test2的toString函式")
return this.value
}
};
alert(test2)
// 呼叫了test的valueOf函式
// 呼叫了test2的toString函式
// 1
其中讓test2 = +test
,那麼即可知道結果,果然如此,呼叫了test
的valueOf
和test2
的toString
示例3
alert(`` + test) // 10 valueOf
同理,我們可以把上一段寫的程式裡面的test2: + test
改成test2:`` + test
示例4
alert(String(test)) // 10 toString
String這個強制轉換其實在其內部是呼叫了傳入引數的toString函式
示例5
alert(Number(test)) // 10 valueOf
示例6
alert(test == `10`) // true valueOf
這個裡面的判等的順序是,獲取原始值,然後判斷兩邊的原始值是否相等,所以呼叫valueOf
示例7
alert(test === `10`) // false
===
操作符不進行隱式轉換,判全等的第一個步驟是判斷型別,因為型別都不一樣了,所以後面什麼都不會呼叫
總結
valueOf
偏向於運算,toString
偏向於顯示。
- 在進行強轉字串型別時將優先呼叫
toString
方法,強轉為數字時優先呼叫valueOf
。 - 在有運算操作符的情況下,
valueOf
的優先順序高於toString
。
下面給大家簡單說下valueof
和tostring
的區別:
-
valueOf()
:返回最適合該物件型別的原始值 -
toString()
: 將該物件的原始值以字串形式返回
這兩個方法一般是交由JS去隱式呼叫,以滿足不同的運算情況。
- 在數值運算裡,會優先呼叫valueOf(),如a + b
- 在字串運算裡,會優先呼叫toString(),如alert(c)