我想知道是否有办法从函数外部访问函数中闭包所捕获的变量;例如如果我有:
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);
答案 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;
}