在Javascript回调中`this`和范围

时间:2015-10-26 03:03:04

标签: javascript jquery scope this

我将直接显示代码:

disable: function(e){
    that = this;
    var haha = this;
    $.post(url, function(){
        console.log(this);// (why ajax object here?
        console.log(that);// (I understand this one works
        console.log(haha);// ReferenceError 
    })
}

我在这里感到困惑的是:

  1. 为什么回调中的this不是指外部的?{1}}?我认为回调中的this遵循默认绑定角色。
  2. 为什么haha没有引用that呢?我认为当在本地范围内找不到haha时,它将转到外部范围。
  3. 我知道使用that不是一个好方法。这就是我尝试haha的原因,但它失败了。 enter image description here

4 个答案:

答案 0 :(得分:3)

我认为您正在尝试从控制台访问这些值...在这种情况下haha将无法正常工作,因为它是函数的本地值,因为您已创建that作为全局变量(因为没有使用var。)

但这是一个错误的模式,因为其他一些脚本可能会在ajax请求完成之前修改that的值。

答案 1 :(得分:2)

问题1的答案是:因为你可以在Javascript中无所畏惧地重新绑定它,jQuery适用于jQuery.post(),因为the documentation for jQuery.ajax()状态:

  

所有回调中的this引用是设置中传递给context的{​​{1}}选项中的对象;如果未指定$.ajax,则context是对Ajax设置本身的引用。

通常:您可能永远不会依赖Javascript库重新绑定this。如果在嵌套回调中需要它的值,只需保存它。在不同的命名变量中,或使用Function.bind()

this

关于jsFiddle的示例:https://jsfiddle.net/millimoose/Lx2oxobg/。对于它的价值,我强烈更喜欢使用单独的变量来提高可读性,因为你可以给它一个描述性的名称,以及$(function() { var self = this; $.post("/echo/json/", (function() { console.log("self", self); // this will be the document itself console.log("this", this); // as will self console.log("self === this", self === this); // should output true }).bind(this)); }); 没有反弹的事实,你已经有效地重新分配了回调的一个参数,并没有一直隐藏在之后这个成功的块。

至于你的问题2,我无法重现它,看到我的第二个小提琴:https://jsfiddle.net/millimoose/zL352rzf/。正如其他人所说,鉴于你的截图,你可能实际上并没有从this本身获得ReferenceError

答案 2 :(得分:2)

尝试使用context的{​​{1}}选项设置$.ajax() thissuccess回调

error

答案 3 :(得分:1)

回调函数在不同的范围内运行,因此它指的是它,而不是它定义的位置。你可以使用bind或apply或call函数来绑定它。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

所以这指的是其他东西,但是因为在声明函数声明的范围内声明它仍然存在于那里。