Javascript 为什么在一个';中声明和定义函数之前可以调用它;谁的剧本?

Javascript 为什么在一个';中声明和定义函数之前可以调用它;谁的剧本?,javascript,function,Javascript,Function,下面是我的意思的一些示例代码,摘自 示例代码: function myMove() { var elem = document.getElementById("myAnimation"); var pos = 0; var id = setInterval(frame, 10); function frame() { if (pos == 350) {

下面是我的意思的一些示例代码,摘自

示例代码:

function myMove() 
    {
          var elem = document.getElementById("myAnimation");
          var pos = 0;
          var id = setInterval(frame, 10);
          function frame()
          {
            if (pos == 350) {
              clearInterval(id);
            } else {
              pos++;
              elem.style.top = pos + 'px';
              elem.style.left = pos + 'px';
            }
          }
    } 
在上述特定示例代码的上下文中,为了具体起见,我将提出相同的问题

问题:

function myMove() 
    {
          var elem = document.getElementById("myAnimation");
          var pos = 0;
          var id = setInterval(frame, 10);
          function frame()
          {
            if (pos == 350) {
              clearInterval(id);
            } else {
              pos++;
              elem.style.top = pos + 'px';
              elem.style.left = pos + 'px';
            }
          }
    } 
为什么setInterval(frame,x)可以调用frame(),即使它是在将setInterval()赋值给 “id”变量减速

背景:
我是一名自学成才的C/C++程序员,正在探索web开发的世界。我读过ES6中变量的“提升”,但我不完全确定函数是否也会发生这种情况。在C++和C中,你不能这样做(从我的理解)!所以,拜托,有人,帮帮我


谢谢大家!

谢谢你。假设您的函数定义将移动到脚本的顶部。就是这样,你可以调用frame(),尽管它的定义在下面

到目前为止,一位主持人[编辑:不是mod!]提供了一个答案,指出

这是一个提升(编程概念)

在JavaScript中:

  • 提升适用于功能
  • 提升适用于“var”类型变量
  • 吊装不适用于:
    • “let”类型变量
    • “常量”类型对象/常量
    • “表达式”(不确定含义)
他提供的链接在这里,解释了许多细微差别:

当您的代码将经历阶段时

  • 汇编
  • 执行
  • 在编译阶段,所有函数声明都将被置于其作用域的顶部

    当您的代码由JS引擎编译时,它将被视为:

    function myMove() 
    {   
    
        function frame()
        {
            if (pos == 350) {
                clearInterval(id);
            } else {
                pos++;
                elem.style.top = pos + 'px';
                elem.style.left = pos + 'px';
            }
        }
        var elem;
        var pos;
        var id;
    
        elem = document.getElementById("myAnimation");
        pos = 0;
        id = setInterval(frame, 10);
    
    } 
    
    注:

  • 所有函数在变量之前被提升
  • 使用
    let
    const
    声明的变量不符合提升条件
  • 不符合吊装条件
  • 编辑:函数表达式:

    还可以使用表达式定义JavaScript函数

    函数表达式可以存储在变量中:

    var x = function (a, b) {return a * b};
    

    函数表达式存储在变量中后,该变量可以用作函数。存储在变量中的函数不需要函数名。它们总是使用变量名调用(调用)

    我相信函数声明:

    growl();
    
    function growl() {
        return "Grr!";
    }
    
    JavaScript将首先运行函数声明代码

    但是,如果我创建这种类型的函数:

    hoot();
    
    var hoot = function() {
        return "hoo! hoo!";
    }
    
    我会得到:

    TypeError: hoot is not a function
    
    为什么??因为我们使用的是一个函数表达式,所以它们并没有被完全提升。我这么说不完全是因为JavaScript已经读取了
    var hoot
    ,但它不知道它的值,所以它会将它设置为
    undefined
    ,并尝试调用
    undefined

    因此,变量被提升,但值没有被提升

    如果我这样做会怎么样

    hoot();
    
    let hoot = function() {
        return "hoo! hoo!";
    }
    
    我将得到以下错误:

    ReferenceError: Cannot access 'hoot' before initialization
    

    为什么??因为未挂起变量声明。因此,错误是我们不能在声明这个函数之前使用它。在hoot存在之前,我们无法访问它,这是有意义的,但您可以通过函数声明和使用
    var
    来访问它。这是JavaScript的一个有趣的怪癖,
    let
    const
    的存在是为了弥补这些意外的后果,例如提升。

    适用于
    函数
    语句(但不是表达式)以及
    var
    声明(但不是
    let
    const
    ),谢谢。伟大的那么,这意味着,在这种情况下,函数语句(即,所述函数的第一个减容和定义)被提升?还有,当你说“不是表达”时,“表达”是什么意思?你的意思是“表达式”吗?在以句子结束符(分号)结尾的语句中?在if(){}语句集(即表达式为“variable==value”)内的参数中的表达式?读取,它解释它。看完后,用一根横木对你大喊大叫,并在使用前申报你的物品哦,谢谢你!我不知道这是一个超链接。:)请参阅以了解函数表达式(以及它们如何不被提升的显式示例)。这里没有主持人。你可以通过版主名字旁边的菱形来识别版主。我只是一个像你一样的用户。谢谢!很抱歉,正如您所知,我是新来的。@PrashanthC我在回答中添加了函数表达式的链接。