目標很簡單
it('處理一下方法調用的this問題', function () {
var scope = {
user={
name: 'wangji',
getName: function () {
return this.name;
}
}
}
var fn = parse('user.getName()');
expect(fn(scope)).toBe('wangji');
});
想想現(xiàn)在是個什么情況纺涤。token解析肯定沒問題,進入primary流程乍惊,遇到user
token的時候生成Constant節(jié)點,然后遇到.
放仗,生成Member節(jié)點润绎,user節(jié)點成為其object屬性,getName成為其property屬性诞挨。往下遇到左括號莉撇,生成Call節(jié)點,剛才生成的Member節(jié)點成為其callee屬性惶傻,然后去查找有沒有參數(shù)棍郎,發(fā)現(xiàn)沒有,于是arguments屬性為空银室。AST構建完成涂佃。
AST
接下來進入編譯階段,進入program遞歸流程蜈敢,進入call節(jié)點巡李,遍歷callee屬性是個member節(jié)點,產生變量V0扶认,進入member節(jié)點的object遞歸侨拦,產生變量v1=scope.user,返回v1辐宾。進入member的property節(jié)點遞歸狱从,完成后設置v0=v1.getName,返回v0。然后在call節(jié)點里面返回v0&&v0()
叠纹。
所以事實上這個函數(shù)里面根本沒有綁定this季研。所以要修改:在函數(shù)調用的時候給這個函數(shù)指明一個上下文。
case ASTBuilder.CallExpression:
var callContext={}; //新增
var callee = this.recurse(ast.callee,callContext);//新增
var arguments=[];
for(var i=0;i<ast.arguments.length;i++){
arguments.push(this.recurse(ast.arguments[i]));
照這個思路今天把功能實現(xiàn)了誉察,但是太困了不想寫筆記了与涡。。持偏。結束吧還是驼卖。。