('b' + 'a' + + 'a' + 'a').toLowerCase()輸出banana的剖析

前言

今天逛微博的時候看到有個博主發的一個問題,代碼以下:函數

('b' + 'a' + + 'a' + 'a').toLowerCase()
// "banana"
複製代碼

當時第一反應是JavaScript會報錯,可是並無。而後就來了興趣ui

剖析

後來仔細一想,估計和JavaScript運算符優先級、隱式轉化有關係。spa

因而先去MDN查了一下JavaScript運算符優先級code

我先把上面代碼用到的運算符和優先級列舉出來:cdn

優先級 運算類型 關聯性 運算符
20 圓括號 n/a (...)
16 一元正號 從右至左 + ...
13 加法 從左至右 ... + ...

OK,瞭解了上面的運算符後,咱們如今來拆分下上面的代碼對象

首先把toLowerCase去掉,這個函數沒啥用,只是起到一個迷惑的做用。blog

'b' + 'a' + + 'a' + 'a'
// to 
'b' + 'a' + (+ 'a') + 'a'
複製代碼

這就是主要的,由於一元正號的優先級是比加法高的,因此這裏用括號標註一下。ip

如今咱們來看下一元正號的說明:字符串

一元正號運算符位於其操做數前面,計算其操做數的數值,若是操做數不是一個數值,會嘗試將其轉換成一個數值。 儘管一元負號也能轉換非數值類型,可是一元正號是轉換其餘對象到數值的最快方法,也是最推薦的作法,由於它不會對數值執行任何多餘操做。它能夠將字符串轉換成整數和浮點數形式,也能夠轉換非字符串值 true,false 和 null。小數和十六進制格式字符串也能夠轉換成數值。負數形式字符串也能夠轉換成數值(對於十六進制不適用)。若是它不能解析一個值,則計算結果爲 NaN。get

注意看上面的這段話:若是操做數不是一個數值,會嘗試將其轉換成一個數值若是它不能解析一個值,則計算結果爲 NaN

那上面代碼的+ 'a'就是會變成NaN,過程以下:

'b' + 'a' + (+ 'a') + 'a'
// to
'b' + 'a' + Number('a') + 'a'
// to
'b' + 'a' + NaN + 'a'
複製代碼

是否是清晰不少了,而後又涉及到了隱式轉化,加號在JavaScript規則裏有一條是,當操做符有一個是字符串類型時,另外一個也要轉成字符串類型。也就是說NaN要進行toString。那NaN在執行是什麼呢?在ECMA-262中有說明,如圖:

Imgur

也就是說NaN會轉成"NaN"。因此上面的代碼就變成了這樣:

'b' + 'a' + NaN + 'a'
// to
'b' + 'a' + "NaN" + 'a'
複製代碼

最終在調用toLowerCase函數轉成小寫,就變成了banana


更正:

沒有必要爲了噴而噴,誠然文章的主體可能並非說有什麼實用價值。可是研究自己就是一件充滿樂趣的事情。開心就好。

不喜歡,關閉就好。於其浪費時間噴一下,不如去看一下其餘的文章。

相關文章
相關標籤/搜索