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

Ali*_*Ali 7 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"
    );

});
Run Code Online (Sandbox Code Playgroud)

我跑了这个并没有用.在我理论化之前我尝试了一些事情,在这个特定的".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"
    );

});
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

阿里

Yeh*_*atz 12

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

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

var hello = function() {
  console.log("Hello " + this);
});
Run Code Online (Sandbox Code Playgroud)

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

hello.call("world") // will print "Hello world"
Run Code Online (Sandbox Code Playgroud)

调用this在作为参数传入之后接受多个参数.一个类似的方法,applythis称为第一个参数,但是将一个参数数组作为第二个参数.

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

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

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

});
Run Code Online (Sandbox Code Playgroud)

这里的问题是,当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"
  );
});
Run Code Online (Sandbox Code Playgroud)

一般来说,当我存储一个本地时,我会存储我可以使用的最具体的元素集,以使回调代码更简单.常见的jQuery习惯用法是做的var self = this,这也很好.

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


p.s*_*rif 5

根据jquery api(在"Callback Function Queues"下)this,任何JQuery AJAX回调函数中的对象将自动指向ajax对象的设置或 - 如果指定 - context对象.

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