有一天,去面試,遇到這樣的題:html
[]+[]
{}+{}
1+[]
複製代碼
???WTF,誰會沒事這麼寫代碼,好吧,我錯了,大佬別打我。懵逼以後要幹嗎?固然是要學習一波,因而我滿世界找資料,有好東西固然是要分享一波,好了,接下來咱們就一塊兒走進 JavaScript 隱式轉換的世界吧。git
在 JavaScript 中加法運算規則很簡單,它只作數字和字符串的加法操做,全部不是這兩種類型的都會被轉換成這兩種原始數據類型再進行操做。github
在 JavaScript 中,數據類型分兩種:面試
那麼對象是如何轉換成原始數據類型的呢?不要慌,咱們繼續看。數組
JS 有一個內部運算 ToPrimitive()
,它用於對象轉換爲原始數據類型。瀏覽器
ToPrimitive(input, PreferredType?)
複製代碼
這個函數接收兩個參數:函數
下面咱們來看一下對於不一樣的參數,它的轉換過程是什麼樣的?學習
valueOf()
方法,若是結果爲原始類型就直接返回。toString()
方法,若是結果爲原始數據類型就返回。參數 String 就不細說了,當參數爲 String 的時候,上面的第二步和第三步交換就好了,也就是先調用 toString()
再調用 valueOf()
。測試
value1 + value2
複製代碼
上面的操做方式以下:ui
// PreferredType被省略,所以非日期爲 Number,日期爲 String。
prim1 = ToPrimitive(value1)
prim2 = ToPrimitive(value2)
複製代碼
這兩個都是 Object 的屬性,能夠本身定義,如今咱們無論,咱們去看看下面幾種狀況這兩個方法返回的都是什麼。
// 對象
const a1 = {
a: 1
};
console.log(a1.valueOf());
console.log(a1.toString());
// 數組
const a2 = [1,2,3];
console.log(a2.valueOf());
console.log(a2.toString());
// 方法
const a3 = function() {
const a = 1;
return 1;
};
console.log(a3.valueOf());
console.log(a3.toString());
複製代碼
將上面的代碼放到控制檯打印一下就知道:
join(',')
的返回值,好比 [1,2,3].toString()
返回 "1,2,3"。好了,根據咱們上面說的,那些面試題簡直灑灑水,咱們來看。
[]+{}
複製代碼
咱們如何去分析呢?在這裏,咱們首先將 [] 和 {} 轉換成原始數據類型,也就是 ToPrimitive([]) 以及 ToPrimitive({}),PreferredType 默認爲 Number,很明顯 [].valueOf()
仍是一個對象,因此咱們繼續,[].toString()
結果爲 "",相同的解析過程 {} 轉換成 "[object Object]"。
好了,如今這個式子是 "" + "[object Object]",咱們知道 + 運算只要有字符串就拼接操做數,因此結果是 "[object Object]"。
可是,在我進行測試的時候,發現了幾個特殊的例子,{}+1
、{}+[]
這兩個例子在控制檯打印出的結果爲 1
和 ""
,很奇怪是吧?我搜了搜資料發現,不一樣瀏覽器對其的解析不一樣,它會將前面一個 {} 當成代碼塊,因而上面的式子就變成了 +1
和 +[]
,因此得出了上面的結果。
好了,通過上面的探究,我相信你們不會再被這些問題難住了,可是要記住,{} 在前面的狀況下可能會由於瀏覽器的差別會形成不一樣的結果,固然,若是你這樣將 {} 用 () 包起來就不會有問題了,或者是先聲明在使用。
更多文章盡在 個人博客倉庫,若是各位讀者以爲有用,歡迎 star,不勝感激。