吊装函数表达式

Hoisting function expression

据我所知只有函数表达式的声明部分被提升而不是初始化。 例如:

var myFunction = function myFunction() {console.log('Hello World');};

所以 "var myFunction;" 被提升了,但 "function myFunction()..." 没有。

现在回答我的问题,我尝试了一下 google 身份验证功能:

"use strict";

$(document).ready = (function() {
  var clientId = 'MYCLIENTID';
  var apiKey = 'MYAPIKEY';
  var scopes = 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/drive.appfolder https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.install https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive.photos.readonly https://www.googleapis.com/auth/drive.scripts';

  $('#init').click(function() {
    gapi.client.setApiKey(apiKey);
    window.setTimeout(checkAuth(false, handleAuthResult), 1);
  });

  var checkAuth = function checkAuth(imm, callback) {
    gapi.auth.authorize({
      client_id: clientId,
      scope: scopes,
      immediate: imm
    }, callback);
  };

  var handleAuthResult = function handleAuthResult(authResult) {
    if (authResult) {
      gapi.client.load('drive', 'v2', initialize);
    } else {
      $('#progress').html('Anmeldung fehlgeschlagen');
    }
  };

  // Other code
})();

在第 10 行 "window.setTimeout(checkAuth..." 我调用了在此函数调用下方声明的 checkAuth 函数。我的假设是我收到一条错误消息“...checkAuth 不是函数/未定义等...”,但它却起作用了。有人可以给我解释一下吗?

那是因为当元素上的实际点击事件被触发时,checkAuthvaluethen可用在范围。您预期的错误将以这种方式发生:

checkAuth(false, ...); // the symbol is available, but...

// its value is assigned here
var checkAuth = function checkAuth() {
    /* more code */
};

请注意 checkAuth() 之前的立即调用,它在上面的代码段中被分配。

调用时可用的是名为checkAuth符号;但是,它的值稍后会被分配。因此错误 checkAuth is not a function 而不是 checkAuth is undefined.

命名函数的声明是 different from assigning a function to a variable. This article 通过示例详细说明了这一点。为了完整起见,我在这里引用重要部分:

we first need to understand the distinction between a function expression and a function declaration. As it’s name implies, a function expression defines a function as part of an expression (in this case assigning it to a variable). These kind of functions can either be anonymous or they can have a name.

... a function declaration is always defined as a named function without being part of any expression.

... the function expression can only be called after it has been defined while the function declaration can be executed both before and after it’s definition

如果删除函数名称,您将得到预期的错误:

 var checkAuth = function(imm, callback) {
    gapi.auth.authorize({
      client_id: clientId,
      scope: scopes,
      immediate: imm
    }, callback);
  };

此外,您似乎错误地使用了 setTimeout:

window.setTimeout(checkAuth(false, handleAuthResult), 1);

将立即执行 checkAuth 而不是延迟它,如果你想延迟执行 checkAuth 你可以将它包装在一个匿名函数中:

window.setTimeout(function() { checkAuth(false, handleAuthResult) }, 1);