在以下代码的多个实例中,我很难弄清“ this”是指什么:

 jQuery(function ($) {

    var coreChat = {

      fetch: function (fn) {
        $.ajax({
          url: "https://api.parse.com/1/classes/chats",
          data: {
             order: 'createdAt',
             limit: 10
          },
          type: "GET"
        })
        .done(function(data) {
          var messages = [];
          for (var i = 0, len = data.results.length; i < len; i++) {
            messages.push(data.results[i].text);
          }

          return fn(messages);
        });
      },

      send: function (message) {
        var data = JSON.stringify({text: message});
        $.ajax({
          url: "https://api.parse.com/1/classes/chats",
          data: data,
          type: "POST"
        });
      },

      display: function (messages) {

        // http://jsperf.com/update-only-text-vs-remove-dom

        var messageNode = $(".messages").find("li");

        messageNode.each(function (i) {
          var $this = $(this);
          if ($this.text() !== messages[i]) {
            $this.text(messages[i]);
          }
        });

      }

    };


    var myChat = {

      init: function () {
        **this**.fetchInitialData();
        **this**.bindSendEvent();
        **this**.refresh();
      },

      fetchInitialData: function () {
        var messagesWrapper = $(".messages");
        for (var i = 0; i < 10; i++) {
          $("<li></li>").appendTo(messagesWrapper);
        }
        myChat.updateMessages();
      },

      bindSendEvent: function () {
        $(".send").on("click", function (e) {
          var input = $(".draft");
          myChat.send(Chat.username + ": " + input.val());
          input.val("");
          e.preventDefault();
        });
      },

      refresh: function () {
        setInterval(function () {
          myChat.updateMessages();
        }, 3000);
      },

      updateMessages: function () {
        this.fetch(function (messages) {
          myChat.display(messages);
        });
      }

    };

    $.extend(myChat, coreChat);
    myChat.init();

  });


更具体地说,在代码的下半部分-myChat对象中,有一个“ init”属性,该属性作为值包含一个函数...

var myChat = {

      init: function () {
        this.fetchInitialData();
        this.bindSendEvent();
        this.refresh();
      },


这里的“这个”指的是什么?在代码的第二行到最后一行将coreChat扩展到myChat的事实是否对确定“ this”所指的内容有所不同?

$.extend(myChat, coreChat);


另外,myChat对象的updateMessages属性中还有一个“ this”。

updateMessages: function () {
        this.fetch(function (messages) {
          myChat.display(messages);
        });
      }


^在这种情况下,这指的是什么?从coreChat提取功能正在“ this”上执行,但是,“ this”又是什么呢?

作为一个切线的问题-在updateMessages函数中,它调用了'fetch'函数.'fetch'与回调函数是异步的('fetch'最初在coreChat对象中找到)。但是,在updateMessages中,作为参数传递来获取的那个函数是什么呢?是否应该执行fetch的原始回调函数,然后将此参数用作回调的参数?我在那里肯定很困惑。

^我理解这是2个独立的问题-如果出现问题,我将其删除,然后将其发布在一个新的独立问题中,但我只是想,因为有人可能已经遍历了整个代码,也许他会/已经具备回答第二个问题的能力,我不妨问一下...

提前致谢!

最佳答案

在您的代码中,“ this”几乎总是指myChat对象。

如果要调用init,则应输入myChat.init()。 init是myChat对象的一部分,因此this引用包含的对象。与其他所有功能一样,在myChat的范围内指定了Init,这意味着该功能和所有其他功能都是myChat的一部分,因此thismyChat

var myChat = {

      init: function () {
        this.fetchInitialData();
        this.bindSendEvent();
        this.refresh();
      },
      ...
}


另外,如果您查看扩展(http://api.jquery.com/jQuery.extend/)上的jquery文档,则描述为“将两个或更多对象的内容合并到第一个对象中”。因此,当您使用$.extend(myChat, coreChat);时,实际上是将所有属性从coreChat复制到myChat对象中。因此,当您在此代码中调用fetch时,实际上是在调用已复制到myChat对象中的fetch方法,因此this仍然引用myChat。为了进一步强调这些方法已添加到myChat对象中,请注意您正在调用myChat.display?那是在coreChat中定义的,但是您正在使用myChat来访问它。

updateMessages: function () {
        this.fetch(function (messages) {
          myChat.display(messages);
        });
      }


在某些情况下,this不引用myChat。即在coreChat的显示功能中。由于您正在使用jquery .each函数,因此在该函数的范围内,this是指正在运行该函数的列表项,而不是coreChat对象(或更准确地说是myChat副本)如上文所述,此coreChat函数的功能)。

var messageNode = $(".messages").find("li");
messageNode.each(function (i) {
          var $this = $(this);
          if ($this.text() !== messages[i]) {
            $this.text(messages[i]);
          }
        });


至于问题的第二部分:

作为参数传递给fetch的函数是fetch完成时的回调函数。 fetch的定义包括一个函数作为参数:

fetch: function (fn) {


.done函数中,调用回调函数,传递消息数据,并返回该回调的结果:

return fn(messages);


因此,您调用.fetch并传入函数,fetch执行并执行其所有处理,然后fetch调用传入的函数。

09-10 01:21