访问由闭包捕获的变量

时间:2010-12-17 16:23:12

标签: javascript

我想知道是否有办法从函数外部访问函数中闭包所捕获的变量;例如如果我有:


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

是否可以在c的实例中访问A。类似的东西:


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

8 个答案:

答案 0 :(得分:16)

闭包范围内的简单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"

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

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

答案 1 :(得分:15)

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

以下是一个例子:

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

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

答案 2 :(得分:8)

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

使用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,但它只是一段简单的代码,证明您可以这样做。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

该模式的重点是防止外部访问“c”。但是你可以访问foo()作为一个方法,所以要在它的范围内看到'c':

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

答案 5 :(得分:0)

如果您只需要访问某些变量并且可以更改核心代码,那么有一个简单的答案不会降低您的代码速度,也不会以任何重要的方式使它关闭。您只需在全局范围内对其进行引用即可。

(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";

概念证明:https://jsfiddle.net/05dxjugo/

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

答案 6 :(得分:0)

如果在您的脚本中以上都不可能,一个非常笨拙的解决方案是将其存储在隐藏的 html 对象中:

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

在外面你可以用

阅读它
document.getElementById("hiddenStore").innerHTML

答案 7 :(得分:-1)

您应该能够使用 if 语句并执行以下操作:

if(VaraiableBeingPasses === "somethingUniqe") {
    return theValueOfC;
}