调用jQuery.post回调函数的上下文是什么?

时间:2009-06-30 15:35:10

标签: javascript jquery

让我们举例说:

$(".button").click(function() {

    $.post("commandrunner.php",
        {
            param1: 'value',
            param2: 'value2',
            param3: 'value3'
        },
        function(data, textStatus) {
            $(this).parent().after('<p>button clicked</p>');
        },
        "json"
    );

});

我跑了这个并没有用。在我理论化之前我尝试了一些事情,在这个特定的“.button”的上下文中没有调用回调,所以$(this)没用。这有效:

$(".button").click(function() {
    var thisButton = $(this);

    $.post("commandrunner.php",
        {
            param1: 'value',
            param2: 'value2',
            param3: 'value3'
        },
        function(data, textStatus) {
            thisButton.parent().after('<p>button clicked</p>')
        },
        "json"
    );

});

这感觉有点像黑客。这是获取对点击按钮的引用的正确方法吗?什么上下文(或任何其他回调)在?

中调用

谢谢!

阿里

4 个答案:

答案 0 :(得分:12)

你在这里注意到的是JavaScript闭包的工作方式。与其他OO语言一样,当调用方法时,它具有“this”,类似于Java的this或Ruby的self。但是,JavaScript this非常具有可塑性,jQuery利用该属性在调用回调时将其设置为有用的值。

在事件的情况下,jQuery将this指针设置为指向绑定事件处理程序的元素。看看这个:

var hello = function() {
  console.log("Hello " + this);
});

如果你来自OO背景,你可能会在困惑中看到上面的片段:this指向的是什么。默认情况下,它将指向全局对象(浏览器中的窗口)。但你可以很容易地覆盖:

hello.call("world") // will print "Hello world"

调用在this之后接受多个参数作为参数传入。一个名为apply的类似方法也会将this作为第一个参数,但会将一个参数数组作为第二个参数。

现在,如果我们再看一下你的例子:

$(".button").click(function() {

    $.post("commandrunner.php",
        {
            param1: 'value',
            param2: 'value2',
            param3: 'value3'
        },
        function(data, textStatus) {
            $(this).parent().after('<p>button clicked</p>')
        },
        "json"
    );

});

这里的问题是,当jQuery再次调用该函数时,它没有使用相同的this调用它。当您创建匿名函数时,它将保留同一范围内的所有本地变量,但不会保留this,它由JavaScript本身(对全局对象)设置或在调用时被覆盖

因此,解决方案是在局部变量中存储指向this的指针,该变量随后可用于闭包。

如上所述,解决方案是:

$(".button").click(function() {
  var parent = $(this).parent();
  $.post("commandrunner.php",
    {
      param1: 'value',
      param2: 'value2',
      param3: 'value3'
    },
    function() {
      parent.after('<p>button clicked</p>')
    },
    "json"
  );
});

通常,当我存储本地时,我会存储我可以使用的最具体的元素集,以使回调代码更简单。常见的jQuery习语是做var self = this,这也很好。

另请注意,JavaScript函数不会检查参数的数量,因此如果您不使用,请将参数留空是完全合法的。它们仍将被传入,但空参数列表将被忽略。

答案 1 :(得分:5)

根据jquery api(在“回调函数队列”下) 任何JQuery AJAX回调函数中的this对象将自动指向ajax对象的设置,或者 - 如果指定 - context对象。

遗憾的是,您无法在$ .post()中指定context

答案 2 :(得分:0)

这是解决问题的正确方法。

查找上下文的最简单方法是使用Firebugconsole.log(this) - 我怀疑它将是XHR对象。

答案 3 :(得分:0)

关键字“this”绑定到函数的范围。要引用其他父作用域,您需要将引用存储在适当的作用域变量中,例如var parentScope = this;