Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么';函数表达式在节点js中的位置是否重要?_Javascript_Node.js_Function Declaration_Hoisting_Function Expression - Fatal编程技术网

Javascript 为什么';函数表达式在节点js中的位置是否重要?

Javascript 为什么';函数表达式在节点js中的位置是否重要?,javascript,node.js,function-declaration,hoisting,function-expression,Javascript,Node.js,Function Declaration,Hoisting,Function Expression,在JavaScript中,当使用函数表达式(例如,var myFunc=function(){…})时,与任何其他变量声明一样,必须在使用它之前定义变量。例如,以下示例将不工作(将导致未捕获类型错误:myFunc不是函数): 但是,在节点js项目的routes/index.js文件中,我有以下代码(明显缩写): myFunc变量在使用后声明为,因此这不应该引发错误吗?这有两个方面: setTimeout(function() { var myVar = myFunc(); }, 0);

在JavaScript中,当使用函数表达式(例如,
var myFunc=function(){…}
)时,与任何其他变量声明一样,必须在使用它之前定义变量。例如,以下示例将工作(将导致
未捕获类型错误:myFunc不是函数
):

但是,在节点js项目的routes/index.js文件中,我有以下代码(明显缩写):


myFunc
变量在使用后声明为,因此这不应该引发错误吗?

这有两个方面:

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

var myFunc = function() {
    // code here...
}
  • 当变量声明位于代码中的
    router.post
    下面时,为什么传递给
    router.post的回调可以访问
    myFunc
    变量

  • 为什么传递给
    router.post
    的回调可以访问分配给
    myFunc
    变量的函数,而该函数直到代码中的变量下方才分配给变量

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

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

    如果不提升
    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() {
        ...
    }
    
    更多关于这方面的信息,请访问我的贫血小博客:

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

    它确实是。您没有遇到问题的唯一原因是,
    myFunc
    在调用您传递到
    router.post
    的回调之前不会使用,这是在运行模块脚本的顶级作用域代码之后(包括创建
    myFunc
    的表达式)

    例如,发生的情况是:

  • 准备工作(创建vars
    router
    myFunc
    并将它们设置为
    undefined

  • express.Router
    调用,为
    Router

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

  • 创建函数,为
    myFunc

  • 稍后,当请求传入时,将调用回调,此时已创建了
    myFunc
    (并且可以访问,因为回调是声明
    myFunc
    的上下文上的闭包)

  • 这与此类似:

    setTimeout(function() {
        var myVar = myFunc();
    }, 0);
    
    var myFunc = function() {
        // code here...
    }
    

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

    调用该函数。那么您是说所有变量都已提升,还是说函数回调中定义的变量都已提升?@jrock2004:所有变量都提升到各自作用域的顶部。@jrock2004:所有
    var
    声明都已处理在进入它们出现的函数(或全局)范围时。这不适用于
    let
    const
    声明(ES2015+)。更多关于我贫血的小博客:有意义-谢谢!(请你解释一下)
    setTimeout(function() {
        var myVar = myFunc();
    }, 0);
    
    var myFunc = function() {
        // code here...
    }