偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

沒有AST, IDE中的錯(cuò)誤提示、自動(dòng)補(bǔ)全、重構(gòu)、語法檢查......都玩不轉(zhuǎn)了

開發(fā) 開發(fā)工具
如果能把JavaScript源碼轉(zhuǎn)化成結(jié)構(gòu)化的對象,就可以精確地知道一段代碼中有哪些變量名,函數(shù)名,參數(shù)...... 這樣就可以寫程序就可以進(jìn)行處理了。

[[257628]]

 張大胖一上班,領(lǐng)導(dǎo)就扔了一個(gè)任務(wù)給他,把項(xiàng)目中的JavaScript代碼做點(diǎn)“小小”的改變:

1. 把 == 改為全等 ===

2. 把parsetInt不標(biāo)準(zhǔn)的調(diào)用改為標(biāo)準(zhǔn)用法 parseInt(xxx)-> parseInt(xxx,10)

對不熟悉JS的同學(xué)稍微解釋一下:

JS在比較兩個(gè)變量的時(shí)候,雙等號將執(zhí)行類型轉(zhuǎn)換; 三等號將進(jìn)行相同的比較,而不進(jìn)行類型轉(zhuǎn)換 (如果類型不同, 只是總會(huì)返回 false );

parseInt(a,10) 表示以十進(jìn)制的方式來解析。

對于這些任務(wù),張大胖腦海中馬上閃現(xiàn)出了解決辦法:字符串替換。

對***個(gè)任務(wù): 找到'==',替換成'==='就行 。

對第二個(gè)任務(wù): parseInt(xxx) 改成parseInt(xxx,10), 沒法直接替換,得寫個(gè)正則表達(dá)式,找到那些只有一個(gè)參數(shù)的parseInt字符串,然后加上一個(gè)新的參數(shù):10 。

張大胖對自己的正則表達(dá)式能力不太自信,如果考慮得不周全,代碼就可能被改壞了。

有沒有別的辦法?

01抽象語法樹

使用正則表達(dá)式,只能把JavaScript源代碼當(dāng)做文本來處理,能力很弱,無法觸及到JavaScript的語法層面,正則表達(dá)式?jīng)]法知道這個(gè)地方是變量,那個(gè)地方是函數(shù)名.....

如果能把JavaScript源碼轉(zhuǎn)化成結(jié)構(gòu)化的對象,就可以精確地知道一段代碼中有哪些變量名,函數(shù)名,參數(shù)...... 這樣就可以寫程序就可以進(jìn)行處理了。

張大胖想起來自己沒有考及格的《編譯原理》,里邊講到了抽象語法樹(AST)不就是所謂結(jié)構(gòu)化的東西嗎?

比如表達(dá)式 result = 6+7*3 , 用抽象語法樹來表示就是:

 

如果把所有的JavaScript代碼都轉(zhuǎn)化成這樣一顆AST的樹,那代碼的一切都盡在掌握, 可以任意修改了。


 

但是這其中有三個(gè)問題:

1. 怎么從文本形式的源代碼形成這么一個(gè)AST ?

讓自己寫程序?qū)崿F(xiàn)那就太難了,得做詞法分析,語法分析等等。

2. 如何遍歷這個(gè)AST,來修改這顆樹的枝枝葉葉?

比如我想在AST這棵樹中添加一個(gè)新的節(jié)點(diǎn),該怎么做?

3. 修改完成以后,怎么再次把AST變成文本的源代碼?

張大胖趕緊打開Google 搜索,很快便找到了三個(gè)開源的工具,正好完成對應(yīng)的三個(gè)功能:

esprima : 從JavaScript源代碼形成AST

estraverse:遍歷樹的節(jié)點(diǎn)并修改

escodegen : 把修改完的AST再次轉(zhuǎn)化為源代碼。

02創(chuàng)建AST

說干就干,張大胖準(zhǔn)備了一段代碼來做實(shí)驗(yàn):

  1. //源碼 
  2. function fun1(opt) { 
  3.     if (opt.status == 1) { 
  4.         console.log('1'); 
  5.     } 
  6.     if (opt.status == 2) { 
  7.         console.log('2'); 
  8.     } 
  9. function fun2(age) { 
  10.     if (parseInt(age) >= 18) { 
  11.         console.log('ok 你已經(jīng)成年'); 
  12.     } 

使用esprima,輕輕松松就把它轉(zhuǎn)化成了抽象語法樹。

  1. //JS語法樹模塊 
  2. const esprima = require('esprima'); 
  3. //創(chuàng)建AST 
  4. const AST = esprima.parseScript(jsCode); 

(由于轉(zhuǎn)成樹后結(jié)構(gòu)非常大,這里不再展示了, 感興趣的同學(xué)自己可以到http://esprima.org/demo/parse.html 去玩一把, 很有趣。 )

比如: if (parseInt(age) >= 18) 這一句,就被轉(zhuǎn)化成了這樣:

 

03遍歷修改AST

有了AST,就可以就是遍歷和修改了,還是使用開源的工具。

  1. //JS語法樹遍歷各節(jié)點(diǎn) 
  2. const estraverse = require('estraverse'); 
  3. //從JS語法樹生成源代碼 
  4. const escodegen = require('escodegen'); 
  5.  
  6. function walkIn(ast){ 
  7.     estraverse.traverse(ast, { 
  8.         enter: (node) => { 
  9.             toEqual(node);//把 == 改為全等 === 
  10.             setParseInt(node); //parseInt(a)-> parseInt(a,10) 
  11.         } 
  12.     }); 

這個(gè)函數(shù)負(fù)責(zé)把‘==’改成‘===’

  1. function toEqual(node) { 
  2.     if (node.operator === '==') { 
  3.         node.operator = '==='
  4.     } 

這個(gè)函數(shù)負(fù)責(zé)把parseInt改成標(biāo)準(zhǔn)調(diào)用:

  1. function setParseInt(node) { 
  2.     //判斷節(jié)點(diǎn)類型 方法名稱,方法的參數(shù)的數(shù)量,數(shù)量為1就增加第二個(gè)參數(shù)。 
  3.     if (node.type === 'CallExpression' && node.callee.name === 'parseInt' && node.arguments.length===1){ 
  4.         node.arguments.push({//增加參數(shù),其實(shí)就是數(shù)組操作 
  5.             "type""Literal"
  6.             "value": 10, 
  7.             "raw""10" 
  8.         }); 
  9.     } 

經(jīng)過這個(gè)函數(shù),原來的 if (parseInt(age) >= 18) 就變成了下圖這樣,相當(dāng)于增加了一個(gè)節(jié)點(diǎn),對應(yīng)的代碼就是 :if (parseInt(age,10) >= 18)

 

***使用escodegen 把修改過的AST再次變成源代碼,就大功告成了:

  1. //生成目標(biāo)代碼 
  2. const code = escodegen.generate(ast); 
  3. //寫入文件..... 
  4. //....你懂的 

通過這個(gè)實(shí)驗(yàn),張大胖基本上了解了AST的原理和用法,接下來可以著手正式的編程了。

04總結(jié)

本文的例子用AST也許不是***解, 主要是為了展示AST的處理技術(shù), AST實(shí)際上就是源代碼的一種結(jié)構(gòu)化表示, 利用它及相關(guān)工具可以方便地優(yōu)化和修改代碼,只要是你能對這棵“AST樹”做“修剪”就可以對源代碼做各種“手腳”:

JavaScript代碼語法、風(fēng)格的檢查

在IDE中的錯(cuò)誤提示、自動(dòng)補(bǔ)全,重構(gòu)

代碼的壓縮和混淆 代碼的轉(zhuǎn)換 ......

有這么強(qiáng)大的功能,AST處理技術(shù)是很多知名工具的基礎(chǔ), 例如babel,webpack,還有jd taro等都把AST用得***。

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】

 

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO
相關(guān)推薦

2012-12-24 09:54:06

大數(shù)據(jù)數(shù)據(jù)科學(xué)家

2020-11-20 11:02:26

AST函數(shù)Javascript

2013-01-10 12:50:38

移動(dòng)游戲人才

2022-01-18 18:46:55

Eslint抽象語法樹Babel

2009-12-09 10:46:06

PHP檢查語法錯(cuò)誤

2009-07-17 14:55:38

ibatis官方

2021-09-14 11:10:20

程序員技能開發(fā)者

2014-05-15 11:02:34

Linux操作系統(tǒng)國產(chǎn)操作系統(tǒng)

2009-06-03 17:00:08

Eclipse自動(dòng)補(bǔ)全

2017-07-04 15:07:44

Windows 7Windows數(shù)據(jù)錯(cuò)誤

2020-12-08 06:20:49

前端重構(gòu)Vue

2020-07-31 07:44:12

代碼自動(dòng)補(bǔ)全

2024-05-10 08:51:31

Python命令補(bǔ)全工具

2022-12-26 00:02:24

重構(gòu)代碼軟件

2017-06-05 14:27:56

MyCLIMySQLMariaDB

2022-01-13 14:06:37

Python 開發(fā)編程語言

2014-12-31 17:12:54

模糊查詢模糊查詢

2024-11-11 00:38:13

Mypy靜態(tài)類型

2016-12-20 09:30:22

shell腳本linux

2011-04-20 08:55:17

BlackBerry
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號