获取周围的JS闭包代码作为文本

Getting surrounding JS closure code as text

本文关键字:文本 代码 闭包 周围 JS 获取      更新时间:2023-09-26

我试图将当前范围的周围js代码作为文本。这意味着之后会嵌入到实时编辑器中。这可能吗?在最坏的情况下,它可以通过Rhino。

thanks a lot

arguments对象有一个成员callee指向当前正在执行的函数:

function example(){
    console.log(arguments.callee.toString())
}

将输出完整的函数定义。所以,这不仅仅是内部代码,还包括周围的function(){...}定义。

一般来说,没有。JavaScript没有提供可靠的方式来内省变量定义或调用堆栈。

只要没有递归调用,

arguments.calleearguments.caller确实提供了对调用堆栈上的函数集的内省,因此您可以通过遍历它来提取源代码。但是它可以被

打败
function defeatArgumentsCaller(f, args, called) {
  if (!called) { return defeatArgumentsCaller(f, args, true); }
  return f.apply(args);
}
function f() {
  defeatArgumentsCaller(g, []);
}

f被调用时,g将无法通过查看arguments.caller来确定它是由f调用的。

function g() {
  var fn = arguments.callee;
  while (true) {
    alert(fn.name);
    var caller = fn.caller;
    // defaultArgumentsCaller is itself, not f.
    if (!caller || caller == fn) { break; }
    fn = caller;
  }
}

它们不允许对已定义的符号集进行自省,例如通过withcatch引入的符号,因此任何试图枚举...中可用的局部变量的尝试

function f(o) {
  try {
    throw null;
  } catch (e) {
    with (o) { 
      ...
    }
  }
}

通过检查调用堆栈和函数源代码将错过一些已定义的符号。

调用堆栈也不同于闭包堆栈。例如,在

function counter() {
  var n;
  return function (f) { return f(n++); };
}
counter()(eval);

eval运行在一个具有比调用堆栈更多的可用符号的上下文中,因为counter在调用eval时不在调用堆栈上。

Rhino允许作为Scriptable访问当前作用域,这暴露了getIds方法,该方法可用于枚举当前堆栈帧中的名称,并且您可以通过getPrototype走到更高的堆栈帧。