在上一篇博客裏面,我們做到了最基本的 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 在,我們還真不怕誰,只要你表達式別寫出問題,我就能給你運行出來,就這麼簡單。
所以,我們現在就又做了一個很小的功能。