简体   繁体   English

Java回调中的this和作用域

[英]`this` and scope in Javascript callback

I will show the code directly: 我将直接显示代码:

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 
    })
}

What I get confused here is: 我在这里感到困惑的是:

  1. Why this in callback does not refer to the outside one? 为什么this在回调中不引用外部的? I think this in callback follow the default binding role. 我认为this在回调中遵循默认绑定角色。
  2. Why haha does not refer as that do? 为什么haha不是指作为that怎么办? I think when haha is not found in local scope, it will go to outer scope. 我认为,如果在本地范围内未找到haha ,它将进入外部范围。

I know using that is not a good way. 我知道使用that不是一个好方法。 That's why I tried haha , but it failed. 这就是为什么我尝试haha ,但失败了。 在此处输入图片说明

I think you are trying to access those values from console... in that case haha will not work as it is local to the function, where as you have created that as a global variable(as there is no var used). 我认为你正试图从控制台访问这些价值观......在这种情况下, haha是行不通的,因为它是本地的功能,在这里为您创建that一个全局变量(因为没有var使用)。

But that is a wrong pattern because some other script could modify the value of that before the ajax request is completed. 但是,这是一个错误的模式,因为一些其他的脚本可以修改的值, that完成Ajax请求之前。

The answer to question 1 is: Because you can rebind it willy-nilly in Javascript, and jQuery happens to for jQuery.post() , as the documentation for jQuery.ajax() states: 问题1的答案是:因为您可以用Java语言重新绑定它,并且jQuery恰好适用于jQuery.post() ,因为jQuery.ajax()的文档指出:

The this reference within all callbacks is the object in the context option passed to $.ajax in the settings; 所有回调中的this引用是context选项中传递给设置中$.ajax的对象; if context is not specified, this is a reference to the Ajax settings themselves. 如果未指定context ,则this是对Ajax设置本身的引用。

Generally: you should probably never rely on a Javascript library to not rebind this . 通常:您可能永远不应该依赖Javascript库来重新绑定this If you need its value in a nested callback, just save it. 如果您需要在嵌套回调中使用其值,则只需保存它即可。 Either in a different-named variable, or using Function.bind() : 在不同名称的变量中,或使用Function.bind()

$(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));
});

Example on jsFiddle: https://jsfiddle.net/millimoose/Lx2oxobg/ . jsFiddle上的示例: https ://jsfiddle.net/millimoose/Lx2oxobg/。 For what it's worth, I strongly prefer using a separate variable for readability, because you can give it a descriptive name, and the fact that this isn't rebound, and that you've effectively reassigned one of the parameters of the callback, isn't hidden all the way after the block for which this holds true. 对于它的价值,我强烈倾向于使用可读性单独的变量,因为你可以给它一个描述性的名称,而事实上, this是不会反弹,而且你已经有效地重新分配了回调的参数之一,ISN 适用于此的代码块之后并没有完全隐藏。

As for your question 2, I can't reproduce it, see my second fiddle: https://jsfiddle.net/millimoose/zL352rzf/ . 至于您的问题2,我无法重现,请参阅第二个小提琴: https : //jsfiddle.net/millimoose/zL352rzf/ As others have stated, you're probably not actually getting the ReferenceError from the console.log() itself, given your screenshot. 正如其他人所述,鉴于屏幕快照,您可能实际上并没有从console.log()本身获取ReferenceError

Try using context option of $.ajax() to set this of success , error callbacks 尝试使用context的选项$.ajax()来设置thissuccesserror回调

disable: function(e) {
    $.ajax({
      context: this
      , type:"POST"
      , url:url 
      , success: function() {
          console.log(this);
        }
      , error: function() {
          console.log(this)
        }
    })
}

The callback function runs in a different its own scope hence this refers to it, not where it was defined. 回调函数在其自己的范围内运行,因此引用该函数,而不是在其定义的位置。 you can use bind or apply or call functions to bind it. 您可以使用bind或Apply或调用函数来绑定它。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

so this refers to something else, but since that is declared in the scope that the function was declared in it still exists there. 因此,它引用了其他内容,但是由于在该函数中声明的范围中声明了该函数,因此该函数在那里仍然存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM