有人可以解释为什么以下不起作用有效:
function displayResults(data) {
$("#odNextPage").click(function() {
alert(data.queryType); // "undefined"
return false;
});
}
为什么我可以在点击匿名函数中使用数据对象?
编辑:我认为没有实际设置queryType属性导致问题,抱歉。鉴于click函数是在数据对象范围之外执行的,我仍然有兴趣让某人解释为什么它现在 工作。
答案 0 :(得分:1)
调用displayResults
的东西控制data
不仅在调用函数时,而且在它返回时(因此在调用回调之前)。调用序列可能如下所示:
data = { /* interesting things */ };
displayResults(data);
delete data.queryType;
// Time passes and then your callback gets called
// but data.queryType is undefined.
我不知道您的具体情况,但上述情况总结了可能发生的情况。
当你在data
上生成一个封闭时,你会抓住data
,但这并不意味着你已经锁定data
内的内容。
现在我们知道data
来自哪里以及为什么它首先被打破了,我们可以在data
正确并且不管它的时候考虑它的工作原理。
创建匿名回调函数时:
function() {
alert(data.queryType);
return false;
}
您正在创建一个封闭,该封闭保留对data
的引用(或更准确地说,data
指向的内容)和data
将不会被删除,直到没有人正在引用它。变量的生命周期取决于其范围;您的data
变量已存在于displayResults
函数中。但是变量只引用(或指向)内存中的对象,并且该对象或多或少会一直存在,直到没有人再引用它为止。
变量名称和被命名的对象是具有不同生命周期的独立实体。引用李小龙的话:
不要专注于手指,否则你会错过所有天上的荣耀。
即使它们没有被称为指针,你也无法摆脱编程中的指针。
答案 1 :(得分:0)
无论范围如何,都应使用getter和setter来跟踪变量赋值。
var data = {};
setDataQueryType('post');
$("#odNextPage").click(function() {
alert(getDataQueryType()); // 'post'
setDataQueryType('get');
alert(getDataQueryType()); // 'get'
return false;
});
// Getter for query type
function getDataQueryType() {
return data.queryType;
}
// Setter for query type
function setDataQueryType(val) {
data.queryType = val;
}