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

时间:2011-12-14 18:31:06

标签: javascript

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

非常感谢

2 个答案:

答案 0 :(得分:4)

arguments对象有一个成员callee,它引用当前正在执行的函数:

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

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

答案 1 :(得分:3)

一般来说,没有。 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将无法通过查看f来确定arguments.caller是否已调用它。

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引入的内容,以便在{/ 1}}

中枚举可用的局部变量的任何尝试
...

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

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

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

function counter() { var n; return function (f) { return f(n++); }; } counter()(eval); 在一个上下文中运行,该上下文中的符号比调用堆栈建议的更多,因为调用eval上的counter不在调用堆栈上。

Rhino允许以Scriptable访问当前作用域,该{{3}}公开eval方法,该方法可用于枚举当前堆栈帧中的名称,并且您可以通过以下方式走到更高的堆栈帧getIds