JavascriptAST編譯器的研究學習

得得啊啊發表於2018-08-10

Javascript AST 編譯器的研究學習

Source:

`use strict`;

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _IceInteractContainer = require(`./InteractContainer`);

var _IceInteractContainer2 = _interopRequireDefault(_IceInteractContainer);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

if (location.host === "xxxx.taobao.com") {
    lib.x = 10
}

exports.default = _IceInteractContainer2.default;
module.exports = exports[`default`];

AST:

https://astexplorer.net/

image

初步觀察

可以得到一些明確的資訊:

  • 整個檔案代表著一個Program
  • JavaScript的程式碼過程被解釋成一個陣列,並在body屬性裡

還有很多未知的資訊,我就暫時先忽略了。

Body

可以看到,裡面有ExpressionStatement、VariableDeclaration、FunctionDeclaration、IfStatement這些例項。
我們對應到原始碼中就不難理解了:

`use strict`;  // AST:ExpressionStatement

Object.defineProperty(exports, "__esModule", { // AST:ExpressionStatement
    value: true
});

var _IceInteractContainer = require(`./InteractContainer`); // AST:VariableDeclaration

var _IceInteractContainer2 = _interopRequireDefault(_IceInteractContainer); // AST:VariableDeclaration

// AST:FunctionDeclaration
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

if (location.host === "xxxx.taobao.com") { // AST:IfStatement
    lib.x = 10
}

exports.default = _IceInteractContainer2.default; // AST:ExpressionStatement
module.exports = exports[`default`]; // AST:ExpressionStatement

看來是將JS進行了歸納,表示式語句、變數描述、函式描述、IF語句等等。
因此不難想象,應該還有While語句等等吧。

ExpressionStatement

Literal

    
    `use strict`;  // AST:ExpressionStatement

image

展開ExpressionStatement,可以看到有個 expression 屬性,這條表示式主要的資訊也就在這了。
值得注意的是 expression 指向的是一個 Literal 例項.

  • type:文字
  • value:值”use strict”

rawValue 和 raw 又有啥區別?(未知)

看起來很簡單,一個字串文字執行語句。
那再繼續看看一個函式呼叫的語句將會變成什麼樣。

CallExpression

Object.defineProperty(exports, "__esModule", { // AST:ExpressionStatement
    value: true
});

image

可以看到 CallExpression 例項有個 calleearguments,代表著誰在呼叫和引數是誰。

callee : MemberExpression

image

這時候我們看到一個新的例項 MemberExpression
這是一個成員表示式,其實我們經歷過這些探究之後,不難想象有什麼能夠編譯成 MemberExpression,比如:
alert(hello.word)裡面的hello.word就會編譯成MemberExpression

MemberExpression

從上圖可以看到,MemberExpression例項有兩個關鍵的屬性,Objectproperty,粗暴的理解就是,`.`(點)前面的就是Object,後面的就是property

但是,hello[0] 的情況呢?
這個就有點意思了,hello[0] 也會被編譯成 MemberExpression的例項。
這個可以自己嘗試和對比下看看。

然後可以看到Object.defineProperty被拆分成了兩個Identifier例項,分別放在了Objectproperty屬性裡面.

Identifier

這個識別符號類,關鍵的就是 name屬性了。
總結下其實可以得出什麼東西會別編譯成Identifier, 例如:

var a = new Function;
a; // AST:Identifier

arguments

值得一說的是,我這裡說的是引數是誰,也就意味著,他可以是任何其他的例項,可能是一個 Literal,可能還是一個CallExpression,又或者是MemberExpression, 但它應該不會是 VariableDeclaration ,IfStatement,嗯,從語法層面來看,是不可能的。
image

嗯。現在看來這個 ObjectExpression是沒有出現和分析過的,不過按照筆者的思路,也可以嘗試去看看這個例項了。~


相關文章