Javascript 访问被闭包捕获的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4472529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:34:23  来源:igfitidea点击:

Accessing variables trapped by closure

javascript

提问by Kiersten Arnold

I was wondering if there is any way to access variables trapped by closure in a function from outside the function; e.g. if I have:

我想知道是否有任何方法可以从函数外部访问函数中被闭包捕获的变量;例如,如果我有:


A = function(b) {
    var c = function() {//some code using b};
    foo: function() {
        //do things with c;
    }
}

is there any way to get access to cin an instance of A. Something like:

有没有什么办法去访问c中的一个实例A。就像是:


var a_inst = new A(123);
var my_c = somejavascriptmagic(a_inst);

采纳答案by psmay

Variables within a closure aren't directlyaccessible from the outside by any means. However, closures within that closure that have the variable in scope can access them, and if you make those closures accessible from the outside, it's almost as good.

闭包中的变量不能通过任何方式从外部直接访问。但是,该闭包中的闭包在范围内可以访问它们,并且如果您使这些闭包可以从外部访问,它几乎一样好。

Here's an example:

下面是一个例子:

var A = function(b) {
    var c = b + 100;
    this.access_c = function(value) {
        // Function sets c if value is provided, but only returns c if no value
        // is provided
        if(arguments.length > 0)
            c = value;
        return c;
    };
    this.twain = function() {
        return 2 * c;
    };
};
var a_inst = new A(123);
var my_c = a_inst.access_c();
// my_c now contains 223
var my_2c = a_inst.twain();
// my_2c contains 446
a_inst.access_c(5);
// c in closure is now equal to 5
var newer_2c = a_inst.twain();
// newer_2c contains 10

Hopefully that's slightly useful to you...

希望这对你有点用......

回答by lama12345

A simple eval inside the closure scope can still access all the variables:

闭包范围内的简单 eval 仍然可以访问所有变量:

function Auth(username)
{
  var password = "trustno1";
  this.getUsername = function() { return username }
  this.eval = function(name) { return eval(name) }
}

auth = new Auth("Mulder")
auth.eval("username") // will print "Mulder"
auth.eval("password") // will print "trustno1"

But you cannot directly overwrite a method, which is accessing closure scope (like getUsername()), you need a simple eval-trick also:

但是您不能直接覆盖访问闭包范围的方法(如 getUsername()),您还需要一个简单的 eval-trick:

auth.eval("this.getUsername = " + function() {
  return "Hacked " + username;
}.toSource());
auth.getUsername(); // will print "Hacked Mulder"

回答by traveller

Answers above are correct, but they also imply that you'll have to modify the function to see those closed variables.

上面的答案是正确的,但它们也暗示您必须修改函数才能看到那些关闭的变量。

Redefining the function with the getter methods will do the task. You can do it dynamically. See the example below

使用 getter 方法重新定义函数将完成任务。你可以动态地做到这一点。看下面的例子

function alertMe() {
    var message = "Hello world"; 
    console.log(message);
}

//adding the getter for 'message'
var newFun = newFun.substring(0, newFun.lastIndexOf("}")) + ";" + "this.getMessage = function () {return message;};" + "}";

//redefining alertMe
eval(newFun);

var b = new alertMe();

now you can access message by calling b.getMesage()

现在您可以通过调用 b.getMesage() 访问消息

Of course you'll have to deal with multiple calls to alertMe, but its just a simple piece of code proving that you can do it.

当然,您必须处理对 alertMe 的多次调用,但这只是一段简单的代码,证明您可以做到。

回答by mwilcox

The whole point to that pattern is to prevent 'c' from being accessed externally. But you can access foo() as a method, so make it that it will see 'c' in its scope:

该模式的重点是防止“c”被外部访问。但是您可以将 foo() 作为方法访问,因此请使其在其范围内看到 'c':

A = function(b) {
    var c = function() {//some code using b};
    this.foo = function() {
        return c();
    }
}

回答by Gareth

No, not without a getter function on Awhich returns c

不,不是没有A返回的 getter 函数c