为什么函数表达式的位置在节点 js 中无关紧要?

Why doesn't the location of a function expression matter in node js?

在 JavaScript 中,当使用函数表达式(例如 var myFunc = function() {...})时,与任何其他变量声明一样,您必须在 之前定义变量 使用它。例如,以下示例将 工作(将导致 Uncaught TypeError: myFunc is not a function):

var myVar = myFunc();

var myFunc = function() {
    // code here...
}

然而,在我的routes/index.js文件中的一个node js项目中,我有如下代码(明显缩写):

var router = express.Router();
.
.
.
router.post('/', function(req, res) {
    ...
    ...
    var myVar = myFunc(); // WORKS!
    ...
    ...
}

var myFunc = function() {
    ...
}

myFunc变量是在使用之后声明的,所以这不应该引发错误吗?

这有两个方面:

  1. 为什么传递给router.post的回调可以访问myFunc变量,当变量声明在下面它在代码中?

  2. 为什么传递给 router.post 的回调可以访问分配给 myFunc 变量的函数,而它直到 才分配给变量 它在代码中?

首先我们将处理变量,然后我们将处理它的值(我们分配给它的函数):

The myFunc variable is declared after it is used, so shouldn't this throw an error?

如果 var 没有被吊起来的话。但是 var 被吊起。因此,当您的模块被加载时,首先 JavaScript 引擎会遍历它以找到所有变量声明和函数声明,处理它们,然后然后 在您的模块中执行分步代码。

例如,对于 JavaScript 引擎,您的模块实际上看起来像这样:

var router = undefined;
var myFunc = undefined;

router = express.Router();
.
.
.
router.post('/', function(req, res) {
    var myVar = undefined;
    ...
    ...
    myVar = myFunc(); // WORKS!
    ...
    ...
}

myFunc = function() {
    ...
}

在我贫血的小博客上有更多相关信息:Poor misunderstood var

Why doesn't the location of a function expression matter in node js?

确实。你没有 运行 陷入麻烦的唯一原因是 myFunc 在你传递给 router.post 回调 之前没有被使用被调用,这是 之后你的模块脚本的顶级范围代码已经 运行 (包括创建 myFunc 的表达式)。

例如,发生的情况是:

  1. 准备工作(创建变量 routermyFunc 并将它们设置为 undefined

  2. express.Router 调用,它将新值分配给 router

  3. 调用router.post,传入但不调用回调函数

  4. 创建函数,将新值赋给 myFunc

  5. 稍后,当有请求进入时,将调用回调,此时 myFunc 已经创建(并且可以访问,因为回调是 myFunc 已声明)

这类似于:

setTimeout(function() {
    var myVar = myFunc();
}, 0);

var myFunc = function() {
    // code here...
}

首先调用setTimeout,然后创建函数并分配给myFunc,然后调用回调函数并通过myFunc调用函数。