提升函数表达式

时间:2015-11-20 17:38:35

标签: javascript hoisting function-expression

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

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

所以" var myFunction;"被提升,但"功能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不是函数/未定义等......",而是它有效。有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

在调用时 可用的是名为checkAuth符号;但是,它的价值会在稍后分配。因此错误 checkAuth不是函数而不是 checkAuth未定义

答案 1 :(得分:1)

通过将函数赋值给变量,声明命名函数是differentThis article通过示例详细阐述了这一点。为了完整起见,我在这里引用了重要的部分:

  

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

     

...函数声明总是被定义为没有命名的函数   成为任何表达的一部分。

     

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

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

 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);