首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定JS/jQuery代码中“这”指的是什么的DIfficulty

确定JS/jQuery代码中“这”指的是什么的DIfficulty
EN

Stack Overflow用户
提问于 2014-02-02 00:58:04
回答 3查看 141关注 0票数 0

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

代码语言:javascript
复制
 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“属性,作为一个值,它包含一个函数.

代码语言:javascript
复制
var myChat = {

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

“这”指的是什么?而coreChat在代码的第2行到最后一行被扩展到myChat这一事实在确定“这”指的是什么方面有什么区别吗?

代码语言:javascript
复制
$.extend(myChat, coreChat);

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

代码语言:javascript
复制
updateMessages: function () {
        this.fetch(function (messages) {
          myChat.display(messages);
        });
      }

在这种情况下,这指的是什么?coreChat的fetch函数是在'this‘上执行的,但是,什么是'this’呢?

作为一个快速切线问题-在updateMessages函数中,它调用'fetch‘函数。’fetch‘是异步的回调函数('fetch’最初在coreChat对象中找到)。但是在updateMessages中,作为要获取的参数传入的函数是什么?fetch应该执行它的原始回调函数,然后这个参数充当回调的参数吗?我在那肯定很困惑。

我知道这是两个不同的问题--如果这是一个问题,我会把它删除,然后把它放到一个新的单独的问题上,但是我只是想,既然有人已经看过整个代码,也许他/她已经有能力回答第二个问题了,我也可以问.

提前谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-02 03:07:36

在您的代码中,"this“通常指的是myChat对象。

如果您要调用init,您将编写myChat.init()。init是myChat对象的一部分,因此this引用包含的对象。Init是在myChat范围内指定的,所有其他函数都是这样,这意味着这个函数和所有其他函数都是myChat的一部分,因此thismyChat

代码语言:javascript
复制
var myChat = {

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

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

代码语言:javascript
复制
updateMessages: function () {
        this.fetch(function (messages) {
          myChat.display(messages);
        });
      }

有一个实例,this不引用myChat。这是在coreChat的显示功能中。由于您使用的是jquery .each函数,因此在该函数的范围内,this引用的是正在运行该函数的列表项,而不是coreChat对象(或者更准确地说,是该coreChat函数的myChat副本,如前所述)。

代码语言:javascript
复制
var messageNode = $(".messages").find("li");
messageNode.each(function (i) {
          var $this = $(this);
          if ($this.text() !== messages[i]) {
            $this.text(messages[i]);
          }
        });

关于你问题的第2部分:

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

代码语言:javascript
复制
fetch: function (fn) {   

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

代码语言:javascript
复制
return fn(messages);

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

票数 1
EN

Stack Overflow用户

发布于 2014-02-02 03:14:57

如果您来自像Java这样的面向对象的世界,“这”是一个有点不同的概念。在Java等语言中,“this”指的是当前正在执行的对象,并由方法的声明方式来定义。但是,在Javascript中,“这”是指函数是如何被调用的,实际上是函数的执行上下文。事实上,引用John在“Javascript的秘密”中的话,它实际上应该被称为调用上下文。

回答你的问题:

  1. thisinit函数中是指myChat对象。不,您使用jQuery.extend合并两个对象的事实与此值无关。这对jQuery来说有点误导。
  2. thisupdateMessages中也指myChat对象

在上面的代码中,需要注意的一件事是refresh中的refresh部分。您的代码是正确的,因为它显式地调用myChat对象上的函数,但在该函数中,this引用全局对象(如果在浏览器中运行,很可能是'window‘)。

最后,为了回答关于回调的第三个问题,fetch运行一个异步帖子。当该帖子完成后,将调用done回调。从该done回调返回的值是调用传递给fetch的函数的值。在您的示例中,这看起来是undefined,因为您的函数调用display,但是display没有指定返回值。默认情况下,任何不指定返回的函数都将返回undefined

希望这能有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2014-02-02 02:43:32

this在JavaScript中取决于如何使用函数本身。它的变化取决于父对象、绑定/应用/调用调用,如果它与构造函数一起使用,等等。关于所有血淋淋的细节,请查看这是关于MDN的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21505739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档