Domanda

In this case, what does the this inside the $.get function refer to?

var articles, verbs, nouns, prepositions, adjectives, words;
articles = ["the", "a"];

this.importData = function() {
    $.get("generator/parts_of_speech/verbs.txt", function(data) {
        this.verbs = data.split("\n");
        **//what does this "this" refer to???**
    });
};

this.importData();

When I write alert(verbs) outside of the $.get function, or even alert(this.verbs), the alert shows up as undefined. I have tried all four cases:

  1. inside the $.get function, write verbs = data.split("\n") and outside of it, write alert(verbs)
  2. inside the $.get function, write verbs = data.split("\n") and outside of it, write alert(this.verbs)
  3. inside the $.get function, write this.verbs = data.split("\n") and outside of it, write alert(verbs)
  4. inside the $.get function, write this.verbs = data.split("\n") and outsideof it, write alert(this.verbs)

And all four of these situations give me an undefined in the alert. What is going on?

È stato utile?

Soluzione

$.get() is asynchronous: Your code isn't going to wait there until $.get sees a result. That result will come back a little bit later -- that's why you give it a callback, because it's not like a regular function call where the code waits until the result is handed directly to the caller. To stretch a metaphor, it's a bit like you're leaving a message. The server will be contacted, and the browser (via jQuery, yada) will call your callback in the near future when it gets a response from the server. In the meantime, your code will already have gone ahead and called alert -- before the response has been received.

So, on to this. this.verbs is not the same as plain verbs. Plain verbs will refer to the one you declared in the var statement. They have nothing to do with each other. They have the same name, but they are different people living on different streets. As it happens, when you assign to this.verbs, you're creating it as a member of a settings object internal to $.get. That doesn't get you anything. Outside of the callback, this will refer to the global window object, unless you're writing your own class, which I doubt.

If you wanted to store verbs in a place where other code can get to it, the plain verbs at the top is the one to use.

The way jQuery uses this is very unclear to new programmers, and there's a solid argument that it's a design flaw. Reasonable people disagree.

Case 1 is the only case that had the slightest hope of working, because it's the only one where you're assigning to outer-scoped verbs and then passing the same variable to alert. It failed anyway, for the timing reason given above.

Try assigning a placeholder value -- "initial verbs value" -- to verbs before you call this.importData(). I expect that you will see that initial value in the alert.

Try your alert call INSIDE the $.get callback. See what you get then. I'm pretty confident you'll see whatever you're getting from the server.

The code that makes use of verbs should be called from that callback, the place where right now you're just assigning it to verbs. The following is my preference. You could just stuff it all in the callback, and lots of people do.

this.importData = function() {
    $.get("generator/parts_of_speech/verbs.txt", function(data) {
        doStuffWithVerbs(data.split("\n"));
    });
};

function doStuffWithVerbs(verbs) {
    //  Whatever you're doing with verbs goes here
}

Altri suggerimenti

what does this "this" refer to???**

It refers to the jQuery settings object.

From $.ajax() - context option

This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax).


From the way your code looks, you want to assign verbs to the object to which the method importData belongs to(assuming you know about the asynchronous nature of ajax requests and how a value set by an async method has to be used).

You can pass a custom context to the callback method using Function.bind()/$.proxy()

this.importData = function () {
    $.get("generator/parts_of_speech/verbs.txt", $.proxy(function (data) {
        this.verbs = data.split("\n");
        //here now `this` refers to the same context on which `importData` was called
    }, this));
};

Another option to do the same is to use a closure variable like

this.importData = function() {
    var self = this;
    $.get("generator/parts_of_speech/verbs.txt", function(data) {
        self.verbs = data.split("\n");
        **//what does this "this" refer to???**
    });
};

In your case, "this" is referring to the global window object. If you went to the console and put in.

this

It will return the window object.

However, inside the $.get it is scoped to the current function.

window.importdata = function() { 
 $.get('sdfs', function() { console.log(typeof this) } 
)};

Logs "Object" but its the xHr object.

All of the variables you have declared are in the global scope. (Window Scope)

var articles, verbs, nouns, prepositions, adjectives, words;

But you are trying to access this.verbs from within a different scope and this.verbs doesn't exist in that function.

Hitting this in the console will return undefined. Which means it has been declared, but there is no value assigned to it.

this.verbs

But inside your function you will get an error I believe. Since you declared those vars in the global scope they are available inside your function just loose the "this" .

verbs = data.split("\n");

I hope this helps.

this inside the function refers to the context of that function so you can only access it either inside this function or... well in your case just inside the function.

verbs is undefined everywhere because you did not assign anything to it, this.verbs outside the $.get is undefined due to the reason above (in other words it's out of its scope)...

so in other words only if you call alert(this.verbs) inside the $.get, you will get some results

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top