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

让我们举个例子说:

$(".button").click(function() { $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function(data, textStatus) { $(this).parent().after('

button clicked

'); }, "json" ); });

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

 $(".button").click(function() { var thisButton = $(this); $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function(data, textStatus) { thisButton.parent().after('

button clicked

') }, "json" ); });

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

谢谢!

阿里

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

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

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

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

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

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

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

 $(".button").click(function() { $.post("commandrunner.php", { param1: 'value', param2: 'value2', param3: 'value3' }, function(data, textStatus) { $(this).parent().after('

button clicked

') }, "json" ); });

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

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

如上所述,解决方案是:

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

button clicked

') }, "json" ); });

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

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

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

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

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

找出上下文的最简单方法是使用Firebug和console.log(this) – 我怀疑它将是XHR对象。

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