调用没有括号的javascript函数

时间:2014-01-05 21:59:30

标签: javascript

以下renderChat函数用于将消息和图像呈现到聊天板上。在函数内部还有另一个函数

var onComplete = function () {

执行创建列表元素并将其附加到聊天列表的所有工作。在onComplete函数之后,只有这三行代码

  img.onload = onComplete;
  img.onerror = onComplete;
  img.src = c.chat.value.media;

因为var onComplete是分配给变量的函数,所以我认为必须用括号调用它。因此,当我看到这个

img.onload = onComplete;

我知道该函数已分配给一个新变量,但从未被调用过。然而,当我使用该应用程序时,聊天已在我们到达img.src = c.chat.value.media;

时呈现

你能解释一下我对JavaScript的理解是怎么回事以及这个函数是如何工作的吗?

 var renderChat = function (c) {
    debug("Rendering chat: key='%s' fingerprint='%s' message='%s' created='%s' imageMd5='%s'",
      c.chat.key,
      c.chat.value.fingerprint,
      c.chat.value.message,
      c.chat.value.created,
      md5(c.chat.value.media));
    var renderFP = c.chat.value.fingerprint;

    if (!isMuted(renderFP)) {
      var img = new Image();
      var onComplete = function () {
        // Don't want duplicates and don't want muted messages
        if (body.find('li[data-key="' + c.chat.key + '"]').length === 0 &&
            !isMuted(renderFP)) {

          var li = document.createElement('li');
          li.dataset.action = 'chat-message';
          li.dataset.key = c.chat.key;
          li.dataset.fingerprint = renderFP;
          li.appendChild(img);

          // This is likely your own fingerprint so you don't mute yourself. Unless you're weird.
          if (userId.val() !== renderFP) {
            updateNotificationCount();

            var btn = document.createElement('button');
            btn.textContent = 'mute';
            btn.className = 'mute';
            li.appendChild(btn);
          }

          var message = document.createElement('p');
          message.textContent = c.chat.value.message;
          message.innerHTML = transform(message.innerHTML);
          li.appendChild(message);

          var createdDate = moment(new Date(c.chat.value.created));
          var timestamp = document.createElement('time');
          timestamp.setAttribute('datetime', createdDate.toISOString());
          timestamp.textContent = createdDate.format('LT');
          timestamp.className = 'timestamp';
          li.appendChild(timestamp);

          var size = addChat.is(":visible") ? addChat[0].getBoundingClientRect().bottom : $(window).innerHeight();
          var last = chatList[0].lastChild;
          var bottom = last ? last.getBoundingClientRect().bottom : 0;
          var follow = bottom < size + 50;

          chatList.append(li);
          setupWaypoints(li);
          debug('Appended chat %s', c.chat.key);

          // if scrolled to bottom of window then scroll the new thing into view
          // otherwise, you are reading the history... allow user to scroll up.
          if (follow) {
            var children = chatList.children();
            if (children.length > CHAT_LIMIT) {
              children.first().remove().waypoint('destroy');
            }

            li.scrollIntoView();
          }
        }
      };

      img.onload = onComplete;
      img.onerror = onComplete;
      img.src = c.chat.value.media;
    }
  };

3 个答案:

答案 0 :(得分:1)

HTMLImageElement对象将导致在适当的时间调用分配给其onloadonerror属性的函数(即,当收到HTTP响应或等待它超时时) )。

执行此操作的代码内置于浏览器中。属性(或更现代代码中的addEventListener函数)是您与该代码交互的唯一方式。

答案 1 :(得分:1)

在Javascript中,您可以将函数存储在变量中,这是您使用onComplete()所做的。 img对象将在成功加载图像(onload)之后执行一个函数(所谓的回调),或者如果它无法加载图像(onerror)。

要告诉img对象在这些事件之后调用哪个方法,你需要给它一个方法名称,如不带括号

  img.onload = onComplete;
  img.onerror = onComplete;

如果你使用括号,函数将立即执行 img.onload将不包含对函数的引用,但是包含onCompleted的结果。

答案 2 :(得分:0)

img.onload = onComplete;会将函数 onComplete分配给onload处理程序。这意味着,当通风口发生时,该功能被调用。

img.onload = onComplete();会将调用函数 onComplete的结果分配给onload处理程序。这意味着,函数被立即调用,期望返回另一个函数(或包含有效JS的字符串),而事件发生时将调用该函数。