解析javascript函数中的外部作用域引用以进行序列化

Jac*_*cob 9 javascript serialization function abstract-syntax-tree dereference

var foo = (function(){
  var x = "bar";
  return function(){
    console.log(x);
  };
})();

console.log(foo.toString()); // function() {console.log(x);}
(foo)(); // 'bar'
eval('(' + foo.toString()+')()')); // error: x is undefined
Run Code Online (Sandbox Code Playgroud)

是否有解析(修改)函数的技术,因此外部作用域的引用成为本地引用,如:

function() {console.log(x);}
Run Code Online (Sandbox Code Playgroud)

变为:

function() {console.log("bar");}
Run Code Online (Sandbox Code Playgroud)

现在,该函数可以通过网络进行字符串化和传输,并在另一个运行时中执行.

也许有人可以将函数解析为抽象语法树然后修改它?引用将永远超出范围(不可用),对吧?

目标:

我正在将过滤器函数从节点运行时序列化到postgresql plv8运行时.现在过滤器函数有接口:dbClient.filter((row,age)=> row.age> age),ageFromOuterScope).then(matches => ...)

我想要接口dbClient.filter((row)=> row.age> age)).then(matches => ...),其中age是外部作用域的引用.

更新:

我只能想象一个解决方案.分析函数,检测函数外部变量的引用,然后重写原始函数:

function(row) {
   return row.age > age
}
Run Code Online (Sandbox Code Playgroud)

至:

function(row, age) {
  return row.age > age
}
Run Code Online (Sandbox Code Playgroud)

检测到的变量也应该添加到表示数组的字符串中,例如:

var arrayString = '[age]'
Run Code Online (Sandbox Code Playgroud)

然后评估字符串:

var functionArgs = eval(arrayString)
Run Code Online (Sandbox Code Playgroud)

最后:

dbClient.filter(modifiedFunction, ...functionArgs).then(matches => ...)
Run Code Online (Sandbox Code Playgroud)

dan*_*vis 0

我通过 Google 的 Closure 编译器运行了你的顶级代码盒的 foo,它给了我这个:

var foo=function(){return function(){console.log("bar")}}();foo;
Run Code Online (Sandbox Code Playgroud)

不完全是你想要的,但是你可以使用 eval() 和/或 toString() 从那里得到你想要的,因为你已经在修改了。

我不知道这有多健壮,并且它使其他代码混乱,但对于您展示的简单函数,它似乎确实一致地内联了代码中出现的非重复基元。