jQuery匿名函数变量范围

时间:2011-08-16 02:07:16

标签: jquery scope anonymous-function

有人可以解释为什么以下不起作用有效:

function displayResults(data) {
    $("#odNextPage").click(function() {
        alert(data.queryType); // "undefined"
        return false;
    });
}

为什么我可以在点击匿名函数中使用数据对象?

编辑:我认为没有实际设置queryType属性导致问题,抱歉。鉴于click函数是在数据对象范围之外执行的,我仍然有兴趣让某人解释为什么它现在 工作。

2 个答案:

答案 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;
}