在JavaScript中删除一个闭包

时间:2010-09-20 08:10:55

标签: javascript closures

有没有办法在JavaScript中拆除闭包以确定函数是什么以及范围是什么?

或者,或许更简洁,有没有办法在JavaScript中序列化闭包?

修改

我想知道是否给出了一个声明如下的函数:

var o = {};
var f = function() { return o; }

有没有办法只看f并找到o?

2 个答案:

答案 0 :(得分:3)

我不确定你的意思是“拆掉封口”。使用 arguments.callee

确定函数是什么
function test () { console.log(arguments.callee); }
// -> function test () { console.log(arguments.callee); }
  

范围是什么?

检查变量是否在范围内的唯一真正方法是尝试访问它。这意味着您需要使用try / catch语句,因为如果您引用未声明的变量,则会引发错误:

try{ myVar; alert("myVar is in scope"); }catch (e){ alert("myVar is not in scope"); }

实际上,如果您编写代码,或者如果您没有编写代码,那么您已经知道哪些变量在范围内。

如果您正在尝试获取堆栈,您可以(使用调用者属性执行此操作),但它是非标准的,可能并非在所有JS实现中都可用 *

function getStack () {
    var stack = [], cFunc = arguments.callee;
    while (cFunc = cFunc.caller)
        stack.push(cFunc);

    console.dir(stack);
}

function func1 () { func2(); }
function func2 () { try { obviousError(); } catch (e) { getStack(); } }

大多数内置开发人员工具以更清晰的方式为您提供堆栈(IE 7和IE 8),因此最好尽可能使用它们。

*目前所有主流浏览器都支持Function.caller。它似乎也在ECMAScript 3.1中定义 - 您可以查看支持here

答案 1 :(得分:1)

如果我理解正确(很难说,即使是最新的编辑),答案也是否定的。闭包的目的之一是封装变量,限制对相关/从属代码组的访问(从全局上下文中分配),以尽量减少名称冲突和/或意外交互。如果您想在全局上下文中访问o,那么您应该在那里定义它。