JavaScript進階(二十八):DOM 的編譯(三)

在上一篇博客裏面,我們做到了最基本的 DOM 編譯,但還有很多的問題。

比如,模板裏面多個空格會怎麼樣?

這個時候,它就報錯了。

原因很簡單,因爲我們現在是拿着空格 a 在用。

 

空格當然要去,也很簡單,我們直接在後面加個 trim 就行:

但是會影響我們的,不止是空格,還有更加複雜的事。

 

那麼接下來,有個小問題需要一些技巧。

W3C 官方,它並沒有給我們提供什麼特別好的辦法來解決這個問題。

或者說,它幫了倒忙,原來有個特好的辦法,但是被它給幹掉了。

 

比如說,我們現在這個表達式 {{a+b}}

首先,我們直接來行不行:

直接報錯了,說在這個 data 裏面,沒有 a+b 這個屬性,那怎麼辦呢?

 

有人可能說,我們可以直接把它 split('+'),然後拿到左右兩邊,我們自己加。

想法不錯,那你有沒有考慮過,它裏面還可能有減號,乘號,除號,或者其他的東西:

這個表達式可以無限加下去,要是看着寫,那就沒法玩了,所以我們必須得偷懶。

那問題的關鍵就來了,怎麼偷懶呢?其實特別的簡單。

相信大家能夠想到一個方法,eval,它可以幫助我們直接來求解一個表達式的值,比方說:

那我們是不是就可以這麼寫:

但是你可以看到,又錯了。

其實 eval,就相當於把那個字符串裏面的代碼,給掏出來,放這一樣。

我們現在執行的 return eval('a+b'),其實就相當於我直接在這寫了個 return a+b:

所以,上面那個 a is not defined 報的一點都不冤。

因爲我們的 a 本來就沒定義。

 

那怎麼辦呢?

曾經有個好辦法,叫做 with。

這個 with,它的作用很簡單,它可以改變我某一塊代碼的作用域。

比方說我們這,這個 str 裏面的東西,它其實是從哪在找的?其實都是從 data 裏面去找的。

所以 a+b,其實就是 this._data.a + this._data.b,那麼我們從理論上來說,是可以用這個 with 來解決問題的:

但是現在你可以看到,報錯了,說嚴格模式下,不能包含 with。

當然可能有人會說,那我不開嚴格模式不就行了嗎?我們一般的項目,絕大多數時候,它都會自帶嚴格模式,所以即使我們這可以,客戶那不行,也還是沒用的。

這就是我們上面說的,曾經有一個還算好使的東西,但是被 W3C 幹掉了。

那爲什麼要幹掉它呢?因爲如果有人亂用,它就會把作用域搞的特別混亂,也會降低代碼的可讀性。

 

既然 with 用不了,那怎麼辦呢?其實很簡單,我們現在要的是什麼?只要有 a 和 b 是不是就不報錯了?

那麼這時候,你可以看到,就不會有問題了。

當然,它上面還有個 name,那我們是不是可以這樣寫:

可以看到,是可以執行的。

 

那如果我在表達式裏面在加點東西呢?比如:

因爲 eval 的執行能力是很強的,eval 它可以解析任何表達式,所以在這個時候你怎麼搞都可以。

並且,如果這時候,我改變一個 a 的值:

你可以看到,這時候也是可以的。

 

所以,我們就剩下一個小小的問題,就是這個申明的變量從哪裏來?

很明顯,我們是不能寫死的,不然萬一 data 裏面又加了個 c,怎麼辦?

 

既然我們能夠 eval 這個字符串,那爲什麼不能在 eval 的徹底一點呢?

比如,我現在給我的這個字符串 str 賦個值,它就等於這一大堆的申明賦值,然後在加上原來 str:

你可以看到,沒問題,一樣能出來。

那麼現在它既然已經變成字符串了,是不是剩下的事就更好辦了呀?

我們可以做一個循環聲明賦值:

這麼寫,大家應該非常容易理解了。

以及最後,我們順便再給這個 arr push 一個 str:

而最後,我們 return 的,也就是 arr.join('')

那麼我們來試試,行不行?

可以看到,報錯了,說不能轉變爲一個字符串。

注意,如果想知道這個錯是怎麼回事,哪一步造成的,我們這得放幾個 console 看看:

那麼你可以看到,問題肯定就出在 arr.join('') 上面。

那麼我們就把它給打印出來,來看看結果:

那麼你可以看到,它給我們出來的就是這樣一個東西。

let a=12,let b=5 都沒問題。

問題就出在 let name=damu 上,如果我們就這樣把它放到裏面去,就是這樣的:

肯定是會報錯的,爲什麼呀?我們有 damu 這個變量嗎?

你別忘了,它現在是個字符串,我們這麼搞肯定是不行的,那怎麼辦?

所以,我們是不是得識別一下,如果它是字符串,我就給它加個引號。

 

那麼,如果每個都要我們去判斷,然後再去加看要不要加引號,就很麻煩,那有沒有簡單直白的方法?還是有的。

有個方法叫做 JSON.stringify。

如果它裏面是個 json,我們都是知道結果的:

你可以看到,它就是一個字符串。

但是,我們很少去讓它應對別的東西,比如我給它一個數字 12:

它出來就是一個字符串 12。

那如果我給它一個 字符串12 呢?

那它出來以後,就是一個引號的 12,這個是不是就是我們要的?

所以就像這樣:

那麼這個時候,我們在來看看這個 console 出來的結果:

你可以看到,這時候就不會有問題了。

那麼我們在放開 return 試試:

可以看到,一切正常。

那麼這時候我還想把這個表達式搞的在複雜一點:

可以看到,現在隨便寫都是可以的。

那如果我們再加了一個新數據 json 呢?

隨便你折騰,因爲它背後是 eval,也許我們沒做多少工作,但是有 eval 在,我們還真不怕誰,只要你表達式別寫出問題,我就能給你運行出來,就這麼簡單。

所以,我們現在就又做了一個很小的功能。

 

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