“这个”在Javascript混乱中

"this." in Javascript Confusion

本文关键字:混乱 Javascript 这个      更新时间:2023-09-26

在这种情况下,$.get函数内部的this指的是什么?

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

当我在 $.get 函数之外写入alert(verbs)时,甚至alert(this.verbs),警报显示为未定义。我已经尝试了所有四种情况:

  1. $.get函数内部,写入verbs = data.split("'n"),在函数外部写入alert(verbs)
  2. $.get 函数内部,写入verbs = data.split("'n"),在函数外部写入alert(this.verbs)
  3. $.get函数内部,写入this.verbs = data.split("'n"),在函数外部写入alert(verbs)
  4. $.get 函数内部,写入this.verbs = data.split("'n"),在函数外部写入alert(this.verbs)

所有这四种情况都给了我在警报中未定义的。这是怎么回事?

$.get()是异步的:你的代码不会在那里等到$.get看到结果。该结果稍后会返回 - 这就是您给它回调的原因,因为它不像常规函数调用,代码会等到结果直接传递给调用者。打个比方,有点像你在留言。将联系服务器,浏览器(通过jQuery,yada)将在不久的将来从服务器获得响应时调用您的回调。与此同时,在收到响应之前,您的代码已经继续并调用了alert

所以,继续this. this.verbs与普通verbs不同。纯verbs将引用您在 var 语句中声明的那个。它们彼此无关。他们有相同的名字,但他们是生活在不同街道上的不同人。碰巧的是,当您分配给this.verbs 时,您正在将其创建为$.get内部设置对象的成员。这不会给你带来任何东西。在回调之外,this将引用全局window对象,除非您正在编写自己的类,我对此表示怀疑。

如果要将verbs存储在其他代码可以访问的位置,则可以使用顶部的普通verbs

jQuery使用this的方式对于新程序员来说非常不清楚,并且有一个坚实的论据认为这是一个设计缺陷。通情达理的人不同意。

案例 1 是唯一有丝毫希望工作的情况,因为它是唯一一个分配给外部范围verbs然后将相同的变量传递给 alert 的情况。无论如何,由于上面给出的时间原因,它都失败了。

尝试在调用 this.importData() 之前将占位符值("initial verbs value")分配给verbs。我希望您会在alert中看到该初始值。

$.get回调中尝试您的alert调用。看看你得到什么。我很有信心你会看到你从服务器得到的任何内容。

使用verbs的代码应该从该回调中调用,现在您只是将其分配给verbs。以下是我的偏好。你可以把它全部塞进回调中,很多人都这样做。

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
}
这个

"这个"指的是什么???**

它指的是 jQuery 设置对象。

从 $.ajax() - 上下文选项

此对象将成为所有与 Ajax 相关的回调的上下文。由 默认情况下,上下文是表示 AJAX 设置的对象 在调用中使用($.ajax设置与传递给的设置合并 $.ajax)。


从代码的外观来看,您希望将verbs分配给方法所属的对象importData(假设您知道 ajax 请求的异步性质以及如何使用异步方法设置的值)。

您可以使用 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));
};

做同样事情的另一种选择是使用闭包变量,例如

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???**
    });
};

在您的情况下,"this"指的是全局窗口对象。如果你去控制台并放入。

this

它将返回窗口对象。

但是,在 $.get 中,它的作用域为当前函数。

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

记录"对象",但它是 xHr 对象。

您声明的所有变量都在全局范围内。(窗口范围)

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

但是您正在尝试从不同的范围内访问 this.verbs,并且该函数中不存在 this.verbs。

在控制台中点击此操作将返回未定义。这意味着它已被声明,但没有为其分配任何值。

this.verbs

但是在你的函数中,我相信你会得到一个错误。由于您在全局范围内声明了这些变量,因此它们在您的函数中可用,只需松开"this"即可。

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

我希望这有所帮助。

函数

内部的this是指该函数的上下文,因此您只能在该函数内部访问它,或者...好吧,在您的情况下,就在函数内部。

verbs到处都是未定义的,因为您没有为其分配任何内容,this.verbs由于上述原因,$.get之外未定义(换句话说,它超出了其范围)......

所以换句话说,只有当你在$.get内部调用alert(this.verbs),你才会得到一些结果