Javascript:可变范围和使用顺序

时间:2015-03-26 14:05:19

标签: javascript ajax

当我尝试进行ajax调用并将函数的动作与自身隔离时,我遇到了一个奇怪的问题。这是代码段



$(document).on('click', 'input.action', function(event) {
    var self = this;
    $.ajax({
        url:'http://date.jsontest.com/',
        method:'GET',
        cache:false,
        dataType:'json',
        success:self.process,
        error:function(){self.process(false);}
    });
    
    self.process = function(data) {
        if (data) {
            
            alert(data.time);
        }
        
        else {
            alert("Operation Failed!");
        }
    }
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container">
    <input type="button" value="Get Time" class="action"/>
</div>
&#13;
&#13;
&#13;

让我简要解释一下我要做的事情,点击按钮,我希望从服务器接收一些数据并显示数据。我正在使用process函数来处理收到的数据。如果出现错误,我会以不同的方式重用process函数来显示错误消息。我只是使用self变量来包含父函数中的所有元素。我完全理解以下内容:

我所知道的

  1. 我没有 使用self来包含process函数,因为其他方法无法访问它
  2. 由于上述代码段中的process方法是在程序的ajax调用之后声明的,因此process函数未定义。
  3. 我清楚知道如何修复它。
  4. 实验

    1. 点击Get Time按钮
    2. 等待,只要你想要,但看不到结果,这是预期的,因为在{ajax调用后声明了process函数
    3. 再次点击Get Time按钮
    4. 现在有效!现在显示一段时间(可能不是你的时间:P)!!
    5. 我想知道的是:

      刚刚发生了什么?为什么它会在第二次和之后的每次运作?请记住, only 适用于ajax调用,如果在调用一次后将赋值保留在函数中,那么这应该适用于所有情况,但事实并非如此。这是一个实验,表明在不使用ajax调用时它的工作方式不同:Fiddle - Experiment

      解决方案:

      我正在根据@Felix Kling的答案添加一个示例解决方案。在Sample Solution中,有两个按钮Get TimeGet Date。我已经附加了参数,以便在time的情况下检索Get Time,并在date的情况下为对象Get Date检索self并且它很有趣一旦我点击Get Time,就像以前一样,没有任何事情发生,但如果我点击Get TimeGet Date第二次只显示时间。

2 个答案:

答案 0 :(得分:1)

这里没有什么“特别”。是的,接受它第一次返回undefined,因为它尚未定义。

但是,您将该函数附加到相同的元素input.action。因此,下次单击按钮时,this 已经附加了process方法,因此再次点击时会调用此方法。

尝试添加一个具有相同类的按钮,然后单击每个按钮一次。现在虽然您点击了第一个按钮,但点击第二个按钮仍然无法创建alert,因为它还没有 附加了process功能。

答案 1 :(得分:1)

  

刚刚发生了什么?

以简化的方式:

var process;
// First click
ajaxCall(process); // process is still undefined
process = function() { ... };

// second click
ajaxCall(process); // process is defined
process = function() { ... };

self.process的分配在事件之间持续存在,因为self引用了相同的元素。

  

这是一个实验,表明在不使用ajax调用时它的工作方式不同:...

由于一个很大的不同,它在你的小提琴中不起作用:你正试图立即执行process。但它不存在,因此会抛出错误。此时脚本终止并且不会执行函数定义发生的函数的其余部分。

在此示例中,process的执行被延迟。脚本“不知道”在收到响应之前没有任何函数可以调用。