3

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

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

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

现在我的问题是,我玩了一下 google auth 功能:

"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 不是函数/未定义等。.. .",但它确实有效。有人可以向我解释一下吗?

4

2 回答 2

2

这是因为当元素上的实际点击事件被触发时,该范围checkAuth内可用。您期望的错误会以这种方式发生:

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

于 2015-11-20T17:45:23.443 回答
1

命名函数的声明不同于将函数分配给变量。本文通过示例详细阐述了这一点。为了完整起见,我在这里引用了重要部分:

我们首先需要了解函数表达式和函数声明之间的区别。顾名思义,函数表达式将函数定义为表达式的一部分(在这种情况下,将其分配给变量)。这些函数可以是匿名的,也可以有名字。

...函数声明始终定义为命名函数,而不是任何表达式的一部分。

...函数表达式只能在定义后调用,而函数声明可以在定义之前和之后执行

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

 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);
于 2015-11-20T17:57:35.043 回答