Javascript 访问闭包捕获的变量

Javascript 访问闭包捕获的变量,javascript,Javascript,我想知道是否有任何方法可以从函数外部访问闭包在函数中捕获的变量;e、 g.如果我有: A = function(b) { var c = function() {//some code using b}; foo: function() { //do things with c; } } 在A的实例中,是否有任何方法可以访问c。比如: var a_inst = new A(123); var my_c = somejavascriptmagic(a_

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


A = function(b) {
    var c = function() {//some code using b};
    foo: function() {
        //do things with c;
    }
}
A
的实例中,是否有任何方法可以访问
c
。比如:


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

不,不是没有
a
上的getter函数,该函数返回
c

该模式的全部要点是防止从外部访问“c”。但是您可以将foo()作为一个方法访问,因此请使其在其作用域中看到“c”:

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

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

下面是一个例子:

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

希望这对您有点帮助…

上面的答案是正确的,但它们也意味着您必须修改函数以查看这些闭合变量

使用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();
现在您可以通过调用b.getMesage()来访问消息


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

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

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"
但您不能直接覆盖访问闭包范围的方法(如getUsername()),您还需要一个简单的求值技巧:

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

如果您只需要访问某些变量,并且可以更改核心代码,那么有一个简单的答案,它不会减慢您的代码速度,也不会以任何明显的方式导致代码关闭。基本上,您只需在全局范围内引用它

(function($){
    let myClosedOffObj = {
        "you can't get me":"haha getting me would be useful but you can't cuz someone designed this wrong"
    };
    window.myClosedOffObj = myClosedOffObj;
})(jQuery);
myClosedOffObj["you can't get me"] = "Got you now sucker";
概念证明:


这也适用于函数或“方法”。

如果脚本中无法实现上述任何一项,一个非常粗糙的解决方案是将其存储在隐藏的html对象中:

// store inside of closure
html.innerHTML+='<div id="hiddenStore" style="display:none"></div>';
o=document.getElementById("hiddenStore")
o.innerHTML="store this in closure"

你能在
a
上动态地定义一个函数吗?或者它必须在
a
的定义中定义吗?好吧,刚才回答了我自己的问题,答案是肯定的否。我猜c只在a=函数{…}的范围内可用。不幸的是,我不能修改a(它在库中)看来大家一致认为c是外部函数无法访问的。一定有办法做到这一点吗(@quinn:你似乎对答案投了否决票,只是因为它们不是你想读的答案…@Gareth是的,我不喜欢这个问题没有答案:(这不是真的:(这很接近,但只有在你能够添加
eval()时才有效)
line与
function alertMe
Wow在同一个闭包中,这个技巧真的很有效。我想不到在现有对象上定义新属性会允许
eval
访问它的任何闭包。这项技术帮助我对通过该网页处理的脚本进行修补,而该脚本在运行时无法被其他任何更改方式。@Dai很高兴它起到了帮助作用,JavaScript在进入肮脏的细节时非常强大和动态。在控制台中测试了这一点,并了解到对方法
toSource()
的支持已经很少了。您可以使用
toString()实现同样的功能
取而代之。Tghis对我不起作用,它说myClosedOffObj在我的网站上还没有定义。
document.getElementById("hiddenStore").innerHTML