javascript元編程之代碼生成

? ? ? ?各位客爺大家好,沉寂了一段時間我們又見面了,這次我和大家討論的方向是javascript的元編程(meta-programming)。

? ? ? ?元編程,什么概念?一個曾經也讓我在面試中打磕巴的東西。

搜了一下維基百科:

? ? ? ?“元編程是一種編程技術,編寫出來的計算機程序能夠將其他程序作為數據來處理。意味著可以編寫出能夠讀取、分析或者轉換其他程序的能力,甚至是在運行時修改程序自身?!?/b>

? ? ? ?上面這行太官方了,如果理解起來吃力的話無所謂,反正我也看不懂.....??

? ? ? ?我們不妨從字義上去理解一下,Meta-Programming,Meta 我們將它直譯為元,而在西方它代表“關于事物自身的事務”,所以以在下愚見,可以魔幻的理解它是:

所謂元編程,就是用代碼去編寫代碼。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ——前端裝逼架構師 Yubble


以下我們逐步來看哈,在學習的過程中,我發現前端的元編程又分為兩個方向:

? ? ? ?1、運行時的動態代碼生成

? ? ? ?2、運行時的語言結構修改,此處我們通常描述為反射

介于反射在元編程中也占了一大部分知識,所以我們今天先重點討論下動態代碼生成這塊兒~

? ? ? ?其實在ECMAscript早期已經出現了元編程方法eval,但是由于此方法安全性差,且在設計初對于動態轉化為機器代碼的性能缺陷,所以各大書籍以及文章中對它的描述都不予看好,但是他也實實在在的實現了用代碼編寫代碼的原則,如下:

? ? ? ?這段代碼意義不大,只是往user對象中塞了一個屬性和值,但是它的運行代碼是包裹在eval方法中,起碼也能說明javascript最開始也是往元編程的方向去靠的.....??

? ? ? ? 觀眾大人:“看了這么半天你就讓我看這些?”

? ? ? ? 各位客爺稍安勿躁,我要拿出點干貨了,就是 new Function~??

? ? ? ? 不知道各位客爺之前有沒有了解過這個寶貝,它其實做的事情和eval一樣,也是用代碼去編寫代碼,具體區別得您自己百度了,話不多說,先上干貨。


業務場景

? ? ? ? 我們是一家寵物商店,在這個網站中我們可以查看到對應寵物的信息,價格,出生地等等。

? ? ? ? 下面是我們已錄入的寵物信息以及后端提供給我們的查詢接口:

? ? ? ? 此時老板告訴我,要將所有出生地非中國的小動物加價5元(多扯淡,數據這東西讓顯示層改??),那么聰明的我們首先先寫了這么一個工廠

????????聰明的你是不是一下子就看出問題了,怎么每個獲取信息方法長得都差不多,不就是調用接口不一樣嗎?所以聰明的你把這個調用接口與通用邏輯做了一個抽象。

? ? ? ? 這樣我把類似邏輯全部抽離出來,代碼就變得清晰多了,如果還有其他的小兔子、小雞、小耗子之類的,給動物工廠增加方法就可以了。但是如果優秀的你足夠高階的話,一定還能搞到更加高效的方法,這就是這偏文章的重點,元編程——動態生成。

? ? ? ? 我們如果真的要搞元編程,那么就離不開一個概念叫’元數據‘,通常是用來描述我們生成的程序的數據。在這個需求里,DS.apis就是我們的元數據。

? ? ? ? 所以,我們可以將DS.apis先傳進來,用這個元數據來動態生成方法。

? ? ? ? 我們改變了這個動物類的結構,首先獲取前面給到的所有api方法,再將api方法便利一次,從而拿到所有api的diff部分,用這些diff部分來調用默認方法define_methods。

? ? ? ? 重點來了,define_methods則將我們前面寫到的通用邏輯整體包裝為一套描述函數內容的字符串,并將這套函數賦予給了Animal的原型。

? ? ? ? 這樣不管是'get_cat_info'還是'get_dog_info'都可以自動生成出來,不管后面還有什么小雞、小鴨、小猴子,都可以讓他們在元數據上做文章,不需要我們手動在類中添加方法了。

? ? ? ? 在使用的時候就是這樣:

? ? ? ? 就這樣,一個勉強的元編程實例編寫完了,其實這個實例代表性還有點勉強,如果將id換成倉庫id就更有說服力了,第一次查找編號為21的倉庫,可以分別查出貓貓與狗狗的信息,第二次再更改個倉庫id,查貓貓狗狗信息。這塊兒只是給大家看一下元編程的應用能力,各位多包涵哈~

使用缺點

? ? ? ? 這種元編程的在工作中也不是面面俱到的。

????????首先它創建函數時必須要是字符串的方式,所以可維護性并不強,所以這類代碼里最好不要代碼業務邏輯。上面這個實例就有待改進,業務和創建原型方法一定要拆開寫,不然后期業務變更需要改代碼可夠受的。

? ? ? ? 其次元編程是十分依賴元數據的準確性和標準化的,如果上游數據出現問題,影響到元編程的執行,那么我們排錯時就會比較麻煩。

? ? ? ? 另外new Function和eval都存在安全方面的隱患,eval更甚,所以這一部分代碼我更傾向于埋到底層執行,避免過度曝光。

結論

? ? ? ? 元編程中動態創建這一塊兒就給各位客官演示完了,根據上面的討論內容,我們也看到了在元數據提供豐富的前提下,前端動態生成函數、方法的可能性。如果您就職在一家類似ToB的公司,整體為元數據驅動的技術背景下,使用元數據來抽出一層動態方法層是完全可行的。


? ? ? ? 終于可以和大家一起聊閑磕了,前段時間剛從上家公司離職,跟老婆一起度了個假,順便把元數據這塊兒整體搞清楚了。說說我上家公司的經歷吧,年初入職了一家成立了20年的公司,司內員工基本司齡6年以上,極為抱團,碰他們的代碼跟搶了他們飯碗似的,幾千行代碼一點注釋沒有,文檔或架構圖就更別提了。領導的管理水平極為感人,提了些流程優化的意見也好像影響到了她的權威一樣。所以和另外一個差不多同期入職的小伙伴不堪重負選擇離職了(后來刷了脈脈才知道,這家公司風評很差,瘋狂內卷,毀約應屆生)。

? ? ? ? 勸各位客官,當下雖然是一個互聯網的下行時代,我們面臨著各種裁員失業,但是也別太心急隨便加入一家公司,如果您有一份穩定的工作,一個動力十足的團隊就踏實干下去。如果收到了一份offer,多刷刷脈脈,看看這家公司風評如何,加班不可怕,可怕的是大家都卷在了內耗上。 ? ? ? ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容