JavaScript進階(三十七):如何拆解一個表達式(二)

上篇博客,我們已經知道如何來拆解一個表達式,那麼接下來,我們就來正式的開始。

首先,我們需要先幹什麼?

我需要先找到兩個左方括號 [[ 出現的地方,從這開始,正式往下做。

所以這時候,我們需要做一個事:

indexOf 有兩個參數:

第一個參數,是我要找什麼。

第二個參數,就是起點,如果你沒給,默認就是 0。

相信大家應該猜到我爲什麼要說這個起點的問題了,因爲接下來很快會用到它。

 

然後找到這個 n 之後,有沒有可能找不到方括號?

比如,它就是一段不需要編譯的普通文本:

所以在這時候,我們需要判斷一下。

如果 n = -1,那我就不理它,換句話說,n 不等於 -1 的時候,我纔開始做事:

那麼接下來,我們就做一個循環,循環的過程當中,i 是從 n+2 開始:

爲什麼從 n + 2 開始?

因爲我們已經確定前 2 個是方括號了,那幹嘛還留着它,直接幹掉不就完了嘛。

 

然後接下來,這事還沒完。

這裏就和我們上篇博客說的一樣,我們有個 count,並且它值是 2:

那麼接下來,我們就做一個事。

我們就看看,this._text 的第 i 個東西,是不是等於右方括號,如果是,那就 count--。

如果是個左方括號,那 count 就 ++

以及我們還要做一個事。

什麼時候,count 變成 0 了,那就說明 OK:

那麼這時候,我們申明一個變量 end。

並且把 i 給賦進去,它就是終點:

並且,如果它減成 0 了,那這個循環還用繼續嗎?就不用了。

所以我們需要加上一個 break,這樣就確保它不會小於 0。

 

當然,還有一種可能,就是我們用這框架的時候,代碼寫錯了。

比如,我們少寫了一個方括號 ]:

那這時候,我們 [ 和 ] 的數量並不相等,那怎麼辦?

所以,當循環整個都結束了以後,如果 count 還是大於 0 的,那這時候我就要報個錯了,因爲表達式是有問題的:

那麼,現在我們手裏有 2 個東西:

一個是 n,就是起點。

還有一個 end,就是終點。

那麼我們的結果就是:

現在我們來打印它看看:

你可以看到,控制檯裏面啥都沒有。

原因很簡單,有人觸發 VText 裏面的這個 render 嗎?並沒有。

 

這裏我們需要把 VComponent 裏面的 render 先寫一下,因爲首先,是 VComponent 最先渲染。

當然順便一說,最頂層的 VComponent,叫做根組件,根組件是所有東西的起點。

然後接下來,我們先把初始渲染放到外面來做,不然會造成重複渲染,比較討厭。

然後 VComponent 裏面的 render 這裏,有個問題了。

我既要渲染我自己,做我自己那個東西的渲染工作之外,我還要渲染我的子級。

這兩件事都要幹,當然,我自己的渲染這事先放着,一步一步來,因爲我們現在主要測的是 text,別的再說。

 

那子級的渲染怎麼做?

別忘了,我們的 VComponent 不是從零開始搞的,它是有父級的,它的父級是 VElement。

既然它的父級是 VElement,那它是不是就有一個東西,叫做 this._children,繼承來的,當然可以用。

那麼接下來呢,我先給子級做渲染,因爲那個 text,也是我的一個子級。

所以在這種情況下,我就需要把我的 _children,來循環一下:

那麼這時候,我就得到一個又一個的 child,我要求我的 child,也做 render:

這很正常,父級渲染了,子級也需要渲染。

那麼現在這時候,在刷新頁面,你就可以看到,打印出來的東西了:

我們要的,是不是就是這個?但是你會發現,少了一個右方括號。

這是因爲 substring,不包括結束位置,所以我們需要 +1。

並且,我們順便做一個事,n = end + 1:

爲什麼?

因爲下一步,就從 n 開始,繼續往下匹配它的下一個表達式。

畢竟一個字符串裏面,是有可能出現多個表達式的:

那麼到現在爲止,你就可以發現,如此複雜的表達式,我們也能解析的了。

當然,我們還有一種拼接字符串的情況,我們也給它加上:

那麼可以看到,這個時候控制檯的解析當然會有問題。

所以,我上面就需要有個 count2,它代表的是單引號的數量。

雙引號我們就先不管了,先處理這一種情況,原理都一樣的。

然後這個時候,我在這除了碰到 [ 和 ],還有可能碰到單引號:

那麼這個時候,我們的 count2 就需要 ++ 了:

然後注意,這時候有一個問題,就是再碰到方括號,這時候我們需要稍微的搞一下:

如果 count2 不等於0,那這時候其實是不需要去加,也不需要去減的。我們不要去動,這時候專心的去等待單引號就行。

換句話說,只有 count2 等於 0 的時候,我們才正常的繼續執行方括號的計數工作:

那麼這時候有一個問題了,就是說這個單引號,它是成堆出現的嗎?

其實不是,你碰到了一個之後,只要再碰到另外一個,它就自然減成 0 了。

所以在這,我們就稍微的做一個判斷。

如果 count2 本來等於 0,說明目前的狀態下,是沒有在等待某個字符串結束的,那麼 count2 就直接等於1,說明這個字符串開始了:

然後 else 的時候,它本來就是 1,那麼我直接就把它變成 0 就行了:

因爲它是不存在加加減減的問題。

那麼現在這時候,我們在看下控制檯:

你可以明確的看到,即使加上單引號的方括號,也是沒問題的。

 

當然有人又說了,還可能有轉義,如果字符串裏面的單引號有轉義的,那怎麼辦,比如像這樣:

所以在這時候,我們碰到字符串之後,先別急着下結論。

我還得做一個事,就是你現在的這個字符串前面,換句話說,它的上一個,還不能等於 \。

就是說,我現在碰到的是一個真字符串,而不是轉義以後的假字符串。

所以這時候,你可以看到,我們這個東西也能正常工作:

那麼到這爲止,我個人認爲,應該也算是能處理很複雜的東西了。

 

當然還有一個問題,有沒有可能,用戶寫錯了?有可能。

比方說,我多加了一個單引號:

那麼現在你可以看到,就是報錯的。

 

那麼這時候如果我們的這個文本里面,有 2 個表達式呢?其實我只能找到一個。

所以,我們 render 裏面的 indexOf 只用一次嗎?不是。

我們下次,是不是以新的 n 作爲起點,再繼續往下找。

換句話說,我這個 n,一開始的時候,是等於 0 的。

然後在我們這個解析的過程當中,總共會碰到幾個表達式?一定是 1 個嗎?不一定,2 個?也不一定,鬼知道有幾個。

所以,我們這邊的循環應該是一個 while 循環。

並且 while 的條件非常的簡單,只要你找完之後不等於 -1,那麼就代表有,有的話,我們就繼續,啥時候沒有,啥時候結束:

那麼現在加了一個循環之後,我們再來試試:

可以看到,就沒有問題了。

我們再隨便加幾個表達式:

可以看到,都是沒問題的。

當然順便一說,我們現在的 s,還得稍微的經過點處理,得掐頭去尾。

因爲開始和結束的方括號我是不要的:

所以,到這爲止,如何從一個字符串裏面,去找到模板,並且把它給擰出來,就已經完成了。

我們已經得到 s 的內容了,那麼剩下的事情,就變的簡單了。

 

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