拆除 JavaScript 中的闭包

发布于 2024-09-24 00:00:29 字数 238 浏览 2 评论 0原文

有没有办法在 JavaScript 中拆掉闭包来确定函数是什么以及作用域是什么?

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

编辑

如果给我一个声明如下的函数,我想知道什么:

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

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

is there a way to tear down a closure in JavaScript to determine what the function is and what the scope is?

Or, maybe more succinctly, is there a way to serialize a closure in JavaScript?

edit

What I am wondering if I am given a function declared as follows:

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

Is there a way to look at just f and find o?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

土豪我们做朋友吧 2024-10-01 00:00:29

我不确定你所说的“拆除封闭”是什么意思。可以使用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"); }

实际上,如果您编写了代码,或者甚至通过检查代码(如果您不这样做),您就已经知道哪些变量在范围内。不写它。

如果您尝试获取堆栈,您可以(某种程度上)使用caller属性来执行此操作,但它是非标准的,并且可能不适用于所有 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 中定义的 - 您可以在此处查看支持.

I'm not sure what you mean by "tear down a closure". Determining what the function is can be done using arguments.callee:

function test () { console.log(arguments.callee); }
// -> function test () { console.log(arguments.callee); }

and what the scope is?

The only real way to check to see if a variable is in scope is by trying to access it. That means you need to use a try/catch statement, because an error is thrown if you refer to an undeclared variable:

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

Realistically you would already know which variables are in scope if you wrote the code or even by examining the code if you didn't write it.

If you're trying to get the stack, you can (sort of) do this using the caller property, but it's non-standard and might not be available in all JS implementations*:

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(); } }

Most built-in developer tools give you the stack (IE 7 and IE 8 don't) in a much clearer manner, so it's best to use them where possible.

* Currently all major browsers support Function.caller. It also appears that it is defined in ECMAScript 3.1 - you can check support here.

秋千易 2024-10-01 00:00:29

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

If I understand you correctly (it's hard to tell, even with your latest edit), the answer is no. One of the purposes of closures is to encapsulate variables, limiting accessibility to groups of related/dependent code (assigned out of the global context), in an effort to minimize name conflicts and/or accidental interaction. If you want to access o in a global context, then you should define it there instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文