在我正在开发的应用程序中,我定义了一个全局App
命名空间,其中我存储了一些我想从不同函数访问的属性。例如,我可能会在我的全局menuOpen
命名空间中保存一个菜单App
属性,因此我用来处理Menu接口功能的函数可以使用处理其他内容的其他函数轻松共享此信息。
我刚才遇到这个问题,用一个函数更新这个全局变量,然后在另一个函数的闭包中检查引用,找到引用didn'反映我的变化。
我在一个简单的例子中重新创建了这个,我希望false
成为结果,因为bar
将open
更改为false
,应该反映出来在state
关闭之前foo
内的state
完成并对//set a global variable to be accessed by different parts
//of an application
var open = true;
//create a closure, which waits for a future event,
//then checks the "open" variable when it occurs
function foo() {
//reference to the global variable "open"
var state = open;
//set a timeout, to reflect "a future event", such
//as an event handler
setTimeout(function() {
if (state) {
$('html').text('true');
} else {
$('html').text('false');
}
}, 1000);
}
//change the "open" global within another function
function bar() {
open = false;
}
//create the closure
foo();
//change "open" to false, before the "if(state)" logic
//is called in the closure
bar();
进行检查:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
state
我的理解是闭包会保留对变量的引用,因此open
会反映对foo
的任何更改。这实际上是如何工作的?我需要做些什么才能让open
的闭包知道var time = '00 : 15 . 13' // Example time format
$.ajax({
type: 'POST',
url: '/time',
dataType: 'json',
data: { time: time }
})
的变化?
答案 0 :(得分:2)
这与闭包无关。 var x = "a"; var y = x; x = "b"; console.log(y)
输出"a"
,而非"b"
,因为y
是x
的副本。
闭包不会改变变量的正常行为。闭包只是一个使用周围范围的局部变量的函数。 foo
是一个闭包,因为它使用open
;传递给setTimeout
的函数是一个闭包,因为它使用state
(但state
在设置后永远不会改变。)
您可以直接查看if (open)
来修复您的代码。
答案 1 :(得分:0)
正如其他人所说,这个问题与闭包没有任何关系。它与Javascript如何分配不同类型有关。
只有Javascript中的对象由指针指定。所有其他数据类型都按值分配(例如,复制值)。所以,当你这样做时:
var state = open;
而且,open
不是一个对象(包括对象,数组和函数),然后open
中的值被复制到state
,然后两个变量都没有彼此做。
见这个例子:
var myNum = 12;
var otherNum = myNum;
document.write("myNum = ", myNum, "<br>"); // 99
document.write("otherNum = ", otherNum, "<br>"); // 12
myNum = 99;
document.write("myNum = ", myNum, "<br>"); // 99
document.write("otherNum = ", otherNum, "<br>"); // still 12
但是,如果您分配了一个对象,它只是一个指向原始对象的指针,因此如果原始对象发生了更改,您会看到对该对象的另一个引用中的更改:
function log(name, obj) {
document.write(JSON.stringify(obj) + "<br>");
}
var myObj = {greeting: "hello"};
var otherObj = myObj;
log("myObj", myObj);
log("otherObj", otherObj);
myObj.greeting = "bye";
log("myObj", myObj);
log("otherObj", otherObj);
通过指针指向原始对象。所有其他类型的变量的行为就像复制它们并且不再与原始变量连接一样。
如果你想获取一个普通的非对象变量并让它表现得像你有一个指向它的指针,那么你可以将该变量作为该对象的属性放入一个对象中,你可以传递该对象。然后,您传递对象的每个人都可以检查该属性,并且他们将查看完全相同的属性值。如果一个人改变它,他们都会看到改变的值。