目标很简单
it('处理一下方法调用的this问题', function () {
var scope = {
user={
name: 'wangji',
getName: function () {
return this.name;
}
}
}
var fn = parse('user.getName()');
expect(fn(scope)).toBe('wangji');
});
想想现在是个什么情况。token解析肯定没问题,进入primary流程,遇到user
token的时候生成Constant节点,然后遇到.
,生成Member节点,user节点成为其object属性,getName成为其property属性。往下遇到左括号,生成Call节点,刚才生成的Member节点成为其callee属性,然后去查找有没有参数,发现没有,于是arguments属性为空。AST构建完成。
接下来进入编译阶段,进入program递归流程,进入call节点,遍历callee属性是个member节点,产生变量V0,进入member节点的object递归,产生变量v1=scope.user,返回v1。进入member的property节点递归,完成后设置v0=v1.getName,返回v0。然后在call节点里面返回v0&&v0()
。
所以事实上这个函数里面根本没有绑定this。所以要修改:在函数调用的时候给这个函数指明一个上下文。
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]));
照这个思路今天把功能实现了,但是太困了不想写笔记了。。。结束吧还是。。