从源码到抽象语法树可视化

JavaScript 代码被执行的时候大致过程如图:

从源码到抽象语法树可视化_第1张图片

其中关键的一个环节是生成抽象语法树(AST)。在词法分析的过程中,JavaScript 引擎把源代码转换成一个个 Token,有人可能就会问什么是 Token。举个例子:

function call() {
    var name = "前端小课";
    if (name) {
        console.log('素燕');
    }
}

把上面的代码进行词法分析,得到的 Token 是这样的:

从源码到抽象语法树可视化_第2张图片

各个标识符的作用如下图所示,每一种标识符都代表着不同的含义。

从源码到抽象语法树可视化_第3张图片

图来自于https://www.cnblogs.com/winter-cn/archive/2012/05/29/2454229.html

有了 token 以后就可以结合语法分析得到抽象语法树:

从源码到抽象语法树可视化_第4张图片

这只是一个简单的 demo,我们再来一个复杂一点的。

function log() {
    console.log(name);
}


function welcome() {
    var name = "前端小课";
    log();
}
var name = "素燕";
welcome();


let number = 0;
function outer() {
    let number = 1;
    function innerTop() {
        let number = 2;
        function innerest() {
            let number = 3;
            console.log('innerest:', number);
        }
        console.log('innerTop:', number);
        innerest();
    }
    console.log('outer:', number);
    innerTop();
}
outer();

我们一起看看经过词法分析后的 Token。

  • Keyword(function)

  • Identifier(log)

  • Punctuator(()

  • Punctuator())

  • Punctuator({)

  • Identifier(console)

  • Punctuator(.)

  • Identifier(log)

  • Punctuator(()

  • Identifier(name)

  • Punctuator())

  • Punctuator(;)

  • Punctuator(})

  • Keyword(function)

  • Identifier(welcome)

  • Punctuator(()

  • Punctuator())

  • Punctuator({)

  • Keyword(var)

  • Identifier(name)

  • Punctuator(=)

  • String("前端小课")

  • Punctuator(;)

  • Identifier(log)

  • Punctuator(()

  • Punctuator())

  • Punctuator(;)

  • Punctuator(})

  • Keyword(var)

  • Identifier(name)

  • Punctuator(=)

  • String("素燕")

  • Punctuator(;)

  • Identifier(welcome)

  • Punctuator(()

  • Punctuator())

  • Punctuator(;)

  • Keyword(let)

  • Identifier(number)

  • Punctuator(=)

  • Numeric(0)

  • Punctuator(;)

  • Keyword(function)

  • Identifier(outer)

  • Punctuator(()

  • Punctuator())

  • Punctuator({)

  • Keyword(let)

  • Identifier(number)

  • Punctuator(=)

  • Numeric(1)

  • Punctuator(;)

  • Keyword(function)

  • Identifier(innerTop)

  • Punctuator(()

  • Punctuator())

  • Punctuator({)

  • Keyword(let)

  • Identifier(number)

  • Punctuator(=)

  • Numeric(2)

  • Punctuator(;)

  • Keyword(function)

  • Identifier(innerest)

  • Punctuator(()

  • Punctuator())

  • Punctuator({)

  • Keyword(let)

  • Identifier(number)

  • Punctuator(=)

  • Numeric(3)

  • Punctuator(;)

  • Identifier(console)

  • Punctuator(.)

  • Identifier(log)

  • Punctuator(()

  • String('innerest:')

  • Punctuator(,)

  • Identifier(number)

  • Punctuator())

  • Punctuator(;)

  • Punctuator(})

  • Identifier(console)

  • Punctuator(.)

  • Identifier(log)

  • Punctuator(()

  • String('innerTop:')

  • Punctuator(,)

  • Identifier(number)

  • Punctuator())

  • Punctuator(;)

  • Identifier(innerest)

  • Punctuator(()

  • Punctuator())

  • Punctuator(;)

  • Punctuator(})

  • Identifier(console)

  • Punctuator(.)

  • Identifier(log)

  • Punctuator(()

  • String('outer:')

  • Punctuator(,)

  • Identifier(number)

  • Punctuator())

  • Punctuator(;)

  • Identifier(innerTop)

  • Punctuator(()

  • Punctuator())

  • Punctuator(;)

  • Punctuator(})

  • Identifier(outer)

  • Punctuator(()

  • Punctuator())

  • Punctuator(;)


通过这些 Token 得到的抽象语法树。

从源码到抽象语法树可视化_第5张图片

而这一过程,其实使用的工具,

https://resources.jointjs.com/demos/javascript-ast,使用它可以轻松把 JavaScript 转换成抽象语法树,这有助于分析 JavaScript 代码。

从源码到抽象语法树可视化_第6张图片

今天主要想把这个工具介绍给大家,以及了解一下 JavaScript 在执行过程中都经历了那些主要的过程。大家加油,如果你有好用的工具欢迎留言分享。


推荐阅读:

用2000字详细解答昨天的题目(再忙也要看一下)

被招安的 JavaScript ,取名为 ECMAScript

我的2019 —我与《前端小课》

你可能感兴趣的:(从源码到抽象语法树可视化)