0

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? I think this in callback follow the default binding role.
  2. Why haha does not refer as that do? I think when haha is not found in local scope, it will go to outer scope.

I know using that is not a good way. That's why I tried haha, but it failed. enter image description here

6
  • What is the "default binding role"? Commented Oct 26, 2015 at 3:04
  • 1
    haha should refer to the same object.... also there is a bug in the code as that is not local to the disable method, some other script could change its value Commented Oct 26, 2015 at 3:06
  • jsfiddle.net/arunpjohny/v1ejqxwd/1 Commented Oct 26, 2015 at 3:07
  • You can also use bind, eg $.post(url, function() { console.log(this) }.bind(this)) Commented Oct 26, 2015 at 3:12
  • @Phil $.post(url, (function() { console.log(this) }).bind(this))? Commented Oct 26, 2015 at 3:13

4 Answers 4

3

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

But that is a wrong pattern because some other script could modify the value of that before the ajax request is completed.

Sign up to request clarification or add additional context in comments.

1 Comment

I put a break point in callback function and prints out those values. Why haha does not work in this way?
2

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:

The this reference within all callbacks is the object in the context option passed to $.ajax in the settings; if context is not specified, this is a reference to the Ajax settings themselves.

Generally: you should probably never rely on a Javascript library to not rebind this. If you need its value in a nested callback, just save it. Either in a different-named variable, or using 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/. 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.

As for your question 2, I can't reproduce it, see my second fiddle: 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.

Comments

2

Try using context option of $.ajax() to set this of success , error callbacks

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

Comments

1

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. https://developer.mozilla.org/en-US/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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.