摘要:操作通常配合來完成。因為是個數組,因此,我們可以直接使用數組操作自我毀滅方法極為簡單,找到要刪除的,執行就結束了。如上述代碼,我們要刪除屬性,代碼如下到目前為止,的我們都介紹完了,下面一篇文章以轉小程序為例,我們來實戰一波。
??通過前兩篇文章的介紹,大家已經了解了Create和Retrieve,我們接著介紹Update和 Remove操作。Update操作通常配合Create來完成。我們這篇文章主要介紹幾個常用的NodePath`API:replace、insert、remove`。具體也可以看babel-handbook中的Manipulation章節。
replaceWith 使用新的節點進行替換 將加法運算替換成乘法const code = `const c = a + b` const ast = babylon.parse(code) traverse(ast, { BinaryExpression(path) { // 注意這里要有判斷,否則會無限進入`BinaryExpression` // https://stackoverflow.com/questions/37539432/babel-maximum-call-stack-size-exceeded-while-using-path-replacewith if (path.node.operator === "+") { path.replaceWith(t.binaryExpression("*", path.node.left, path.node.right)) } } }) console.log(generate(ast, {}, code).code) // const c = a * b;將this.count替換為this.data.count
??轉換前后的AST展示如下圖:
??我們需要做的是,找到符合this.count的ThisExpression,然后把它替換為this.data
const code = `this.count` const ast = babylon.parse(code) traverse(ast, { MemberExpression(path) { if ( t.isThisExpression(path.node.object) && t.isIdentifier(path.node.property, { name: "count" }) ) { path .get("object") // 獲取`ThisExpresssion` .replaceWith( t.memberExpression(t.thisExpression(), t.identifier("data")) ) } } }) console.log(generate(ast, {}, code).code) // this.data.count;replaceWithSourceString 直接使用代碼替換
??上個例子中將this.count替換為this.data.count的部分,通過t.memberExpression可以構造node。更簡單的操作可以直接使用replaceWithSourceString,個人覺得這個API很好用。
path.get("object").replaceWithSourceString("this.data")插入操作
??插入是樹操作的一種常見操作。子節點是個Array,前、中、后各種位置都可以插入新節點。下面來介紹下pushContainer、unshiftContainer、insertBefore、insertAfter操作。
??這里以給obj對象新增一個屬性myprop: "hello my property"為例:
const code = ` const obj = { count: 0, message: "hello world" } ` const ast = babylon.parse(code) const property = t.objectProperty( t.identifier("myprop"), t.stringLiteral("hello my property") )pushContainer 父節點的操作
??父節點為子節點Array插入一個node
traverse(ast, { ObjectExpression(path) { path.pushContainer("properties", property) } })insertAfter 兄弟節點的操作
??insertAfter也可以完成上述操作,需要找到message屬性,然后在后面插入node就搞定啦
traverse(ast, { ObjectProperty(path) { if ( t.isIdentifier(path.node.key, { name: "message" }) ) { path.insertAfter(property) } } })
??unshiftContainer和insertBefore與上面兩個相對應,這里不再舉例了,大家可以自己試一試。
??因為properties是個數組,因此,我們可以直接使用數組操作
traverse(ast, { ObjectExpression(path) { // path.pushContainer("properties", property) path.node.properties.push(property) } })Remove 自我毀滅
??Remove方法極為簡單,找到要刪除的NodePath,執行Remove就結束了。如上述代碼,我們要刪除message屬性,代碼如下:
traverse(ast, { ObjectProperty(path) { if ( t.isIdentifier(path.node.key, { name: "message" }) ) { path.remove() } } })
到目前為止,AST的CURD我們都介紹完了,下面一篇文章以vue轉小程序為例,我們來實戰一波。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107868.html
摘要:針對語法樹節點的查詢操作通常伴隨著和這兩種方法見下一篇文章。注意上述代碼打印出的和中的并不完全一致。如函數,在中的為,但其實際的為。這個大家一定要注意哦,因為在我們后面的實際代碼中也有用到。 ??在上一篇文章中,我們介紹了AST的Create。在這篇文章中,我們接著來介紹AST的Retrieve。??針對語法樹節點的查詢(Retrieve)操作通常伴隨著Update和Remove(這兩...
摘要:生成屬性這一步,我們要先提取原函數中的的對象。所以這里我們還是主要使用來訪問節點獲取第一級的,也就是函數體將合并的寫法用生成生成生成插入到原函數下方刪除原函數程序輸出將中的屬性提升一級這里遍歷中的屬性沒有再采用,因為這里結構是固定的。 ??經過之前的三篇文章介紹,AST的CRUD都已經完成。下面主要通過vue轉小程序過程中需要用到的部分關鍵技術來實戰。 下面的例子的核心代碼依然是最簡單...
摘要:思路可以實現時間復雜度的和,但是要求也是,只用是不可以的。但是在里面查找的時間復雜度依然是,可以想到用來記錄對應的,這樣查找的時間也是常數。用可以保持順序,但是的時間復雜度是。 380. Insert Delete GetRandom O(1) Design a data structure that supports all following operations in aver...
吃豆人和削蘋果這兩個游戲想必大家都知道吧,本文運用Python里的Pygame控制模塊編寫出一個融合吃豆人+切水果的新手游:玩命吃蘋果,有興趣的話可以認識一下 引言 哈哈哈!木木子今天浮現——早已來給大家看了不少具體內容啦~ 涉及到的人工智能、新手、網絡爬蟲、數據統計分析(這一塊的通常但是審批)手機游戲... PS: 吃豆人我寫過了哈 Python+Pygame實戰之吃豆豆游戲的實...
摘要:首先要做到是,能想到的數據結構只有兩三種,一個是,一個是,是,還有一個,是。不太可能,因為長度要而且不可變,題目也沒說長度固定。可以做到和都是。因為還有函數,要可以,所以還需要一個數據結構來記錄順序,自然想到。 LRU Cache 題目鏈接:https://leetcode.com/problems... 這個題要求O(1)的復雜度。首先要做到get(key)是O(1),能想到的數據結...
閱讀 1757·2021-11-11 16:55
閱讀 2545·2021-08-27 13:11
閱讀 3621·2019-08-30 15:53
閱讀 2300·2019-08-30 15:44
閱讀 1378·2019-08-30 11:20
閱讀 1035·2019-08-30 10:55
閱讀 941·2019-08-29 18:40
閱讀 3028·2019-08-29 16:13