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:
初步观察
可以得到一些明确的信息:
- 整个文件代表着一个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
展开ExpressionStatement,可以看到有个 expression
属性,这条表达式主要的信息也就在这了。
值得注意的是 expression
指向的是一个 Literal
实例.
- type:文本
- value:值"use strict"
rawValue 和 raw 又有啥区别?(未知)
看起来很简单,一个字符串文本执行语句。
那再继续看看一个函数调用的语句将会变成什么样。
CallExpression
Object.defineProperty(exports, "__esModule", { // AST:ExpressionStatement
value: true
});
可以看到 CallExpression
实例有个 callee
和 arguments
,代表着谁在调用和参数是谁。
callee : MemberExpression
这时候我们看到一个新的实例 MemberExpression
这是一个成员表达式,其实我们经历过这些探究之后,不难想象有什么能够编译成 MemberExpression
,比如:
alert(hello.word
)里面的hello.word就会编译成MemberExpression
MemberExpression
从上图可以看到,MemberExpression
实例有两个关键的属性,Object
和property
,粗暴的理解就是,'.'(点)前面的就是Object
,后面的就是property
。
但是,hello[0] 的情况呢?
这个就有点意思了,hello[0] 也会被编译成 MemberExpression
的实例。
这个可以自己尝试和对比下看看。
然后可以看到Object.defineProperty
被拆分成了两个Identifier
实例,分别放在了Object
和property
属性里面.
Identifier
这个标识符类,关键的就是 name
属性了。
总结下其实可以得出什么东西会别编译成Identifier
, 例如:
var a = new Function;
a; // AST:Identifier
arguments
值得一说的是,我这里说的是参数是谁
,也就意味着,他可以是任何其他的实例,可能是一个 Literal
,可能还是一个CallExpression
,又或者是MemberExpression
, 但它应该不会是 VariableDeclaration
,IfStatement
,嗯,从语法层面来看,是不可能的。
嗯。现在看来这个 ObjectExpression
是没有出现和分析过的,不过按照笔者的思路,也可以尝试去看看这个实例了。~