將值從一種類型轉換爲另外一種類型一般稱爲類型轉換,這是顯示的狀況。隱式的狀況稱爲強制類型轉換,在JavaScript中存在不少隱式類型轉換的狀況javascript
6種原始類型(基本數據類型):前端
Object (引用類型):vue
基本類型(基本數值、基本數據類型)是一種既非對象也無方法的數據。在 JavaScript中,共有6種基本類型:string,number,boolean,null,undefined,symbol (ECMAScript 6)。java
這裏就要提到原生類型內建的包裝對象,包括:node
在操做原始數據類型的屬性和方法時,JS會自動將原始類型轉換成一個對應的包裝對象。此時該對象就擁有了屬於它自己的一系列屬性和方法。因此當咱們定義了一些基本數據類型,想訪問其對應的屬性或方法時,就須要將其轉換爲這個值的包裝對象,然而現實中並不須要這麼麻煩,這是由於JS運行的宿主對象(瀏覽器等)將會自動地包裝基本類型值來知足這樣的訪問。因此我認爲所謂JS萬物皆對象,或許只是自動的實現了一些隱式的轉換。react
關於 === 和 == 比較操做符的不一樣,在比較淺顯的認知中,全等操做符(===)會比較類型,而比較運算符(==)則不會比較類型。 然而咱們看一下其在MDN中的定義:webpack
全等操做符(===)比較兩個值是否相等,兩個被比較的值在比較前都不進行隱式類型轉換。 相等操做符(==)比較兩個值是否相等,在比較前將兩個被比較的值轉換爲相同類型。web
由此得出這兩個操做符最大的不一樣,就是在比較前是否會進行隱式類型轉換。算法
咱們也常常會見過不少隱式轉換比較的題目,如:數組
undefined == null //true
[] == [] //false
[] == ![] //true
{} == !{} //false
![] == {} //false
[] == !{} //true
[1,2] == ![1] //false
複製代碼
因此上述的是依據什麼規則如何進行轉換?在ECMA文檔中的抽象相等比較算法具體描述了以下規則。
在比較x == y,其中 x 和 y 是值,結果返回 true 或 false 。比較規則以下:
a. 若是x的類型爲Undefined,返回true。
b. 若是x的類型爲Null,返回true。
c. 若是x的類型爲Number,則以下:
i. 若是 x 爲 NaN, 返回 false.(NaN == NaN 爲false)
ii. 若是 y 爲 NaN, 返回 false.
iii. 若是 x 和 y 的值相同, 返回 true.
iv. 若是x爲+0,y爲−0,返回 true.
v. 若是x爲−0,y爲+0,返回 true.
其餘返回 false.
d. 若是x是string類型,那麼假如x和y是徹底相同的字符序列(相同的長度和相應位置的相同字符),則返回true。不然,返回false。
e. 若是x是布爾類型,假如x和y都爲true或都爲false,則返回true。不然,返回false。
f. 若是x和y引用同一對象,則返回true。不然,返回false。
複製代碼
2. 若是x爲null,y爲undefined,則返回true。
3. 若是x爲undefined,y爲null,則返回true。(其他的任何類型與undefined和null相比都爲false)
4. 若是x是數字類型,y是字符串類型,則返回x == ToNumber(y)的比較結果.
5. 若是x是字符串類型,y是數字類型,則返回ToNumber(x) == y的比較結果.
6. 若是x是布爾類型,則返回ToNumber(x)==y的比較結果.
7. 若是y是布爾類型,則返回x == ToNumber(y)的比較結果.
8. 若是x是字符串或數字類型,y 是對象類型,返回比較結果x== ToPrimitive(y)。
9. 若是x是對象類型,y是字符串或數字類型,返回比較結果ToPrimitive(x)==y。
10. 其餘則返回false
複製代碼
抽象操做ToNumber將非數字值轉換爲數字類型。
抽象操做ToPrimitive將引用類型轉爲基本數據類型。
JS引擎內部轉換爲原始值ToPrimitive(obj,preferredType)函數接受兩個參數,第一個obj爲被轉換的對象,第二個preferredType爲但願轉換成的類型(默認爲空,接受的值爲Number或String)
在執行ToPrimitive(obj,preferredType)時若是第二個參數爲空而且obj爲Date的實例時,此時preferredType會被設置爲String,其餘狀況下preferredType都會被設置爲Number若是preferredType爲Number。
轉換爲Number數字類型的過程爲首先調用obj.valueOf(),若是執行結果是基本數值類型就返回該值,不然就調用obj.toString(),返回該字符串類型值。
轉換爲String數字類型的過程爲首先調用obj.toString(),若是執行結果是基本數值類型就返回該值,不然就調用obj.valueOf(),返回該字符串類型值。
上述規則總結起來基本就是:
在上圖測試結果總結以下:
由此能夠看出,對象、數組、日期類型最後基本都被轉換爲字符串類型。因此咱們姑且能夠將ToPrimitive看作將引用類型最後都轉換爲字符串類型。
抽象操做ToBoolean將轉爲布爾類型。
對於布爾類型轉換來講,假值(undefined、null、false、+0、-0、NaN、"")會被轉換爲false,除假值外的全部值都會被轉換成true。
抽象操做ToString將轉爲字符串類型。
對於字符串類型也比較好理解,大部分的基本數據類型轉換爲字符類型時,基本就是在它基礎上加了引號這麼直觀,比較特殊的就是+0、0、-0它們幾個都會被轉成相同的'0',還有那些極小和極大的數字將會轉換爲指數形式的字符串來表現,而引用類型轉換成字符串的時候也跟它們ToPrimitive時候的規則一致(見上文ToPrimitive)。