褚念荣 2024-04-20 13:54 采纳率: 42.9%
浏览 2
已结题

javascript 函数作用域

遇到的问题

不是说:JavaScript中使用 function 关键字定义的函数具有函数作用域或全局作用域,并不受块级作用域的限制 为什么 函数定义if else块前 调用函数 报错了

问题代码

let age = 16; //16 作为例子
// welcome();    // 报错, 没有声明  js文件是从上往下执行 为什么line2  找不到welcome方法  line6 可以正常执行
if (age < 18) {
  let a = "我说let 字符串";

  welcome();               // \   (运行)
                           //  |
  function welcome() {     //  |
    alert("Hello!");       //  |  函数声明在声明它的代码块内任意位置都可用
  }                        //  |
                           //  |
  welcome();               // /   (运行)

} else {

  function welcome() {
    alert("Greetings!");
  }
}

// 在这里,我们在花括号外部调用函数,我们看不到它们内部的函数声明。


welcome(); // 不报错  ,期望报错的

confirm.alert(a);  // 报错了  

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-20 13:54
    关注

    引自免费微信小程序:皆我百晓生

    在 JavaScript 中,函数的作用域规则确实与变量的作用域不同。当您在一个代码块(例如 if-else 块)内部声明一个函数时,这个函数的作用域会扩展到整个包含它的函数或脚本,而不仅仅是那个代码块。这是因为在 JavaScript 中,函数声明语句的行为类似于 var 声明,会在当前作用域的顶部被提升(hoisted)。这意味着无论函数声明的位置如何,都会先于其实际声明的位置进行解析。

    但是,在 JavaScript 中,let 和 const 声明的变量遵循块级作用域,它们仅在其声明所在的代码块内有效。因此,如果您在 if 或者 for 等控制结构内部使用 let 声明变量,这些变量只在这个控制结构的范围内是可访问的。

    在您的代码示例中,welcome() 函数的声明是在 if 代码块内部,所以它在 if 代码块中是可访问的。当您在 if 代码块内部调用 welcome() 时,它是可以找到并正确执行的。而在 if 代码块外部,由于没有局部的 welcome() 函数声明,全局作用域中的 welcome() 函数引用会立即抛出错误,因为这时函数还未声明。然而,因为函数声明会被提升,所以在外部再次调用 welcome() 时,它不再报错,而是执行了在 if 代码块之后声明的全局版本的 welcome() 函数。

    至于变量 a,它也是在 if 代码块内部声明的,所以它也只在 if 代码块内部有效。尝试在 if 代码块外部访问 a,比如通过 confirm.alert(a),会导致错误,因为此时 a 是未定义的。

    下面是修改后的代码,将 welcome() 的声明移动到 if 代码块之外,使其成为全局函数,同时将 a 移动到适当的位置,以便在 if 代码块内外都能访问:

    let age = 16;
    
    function welcome() {
      alert("Hello!");
    }
    
    if (age < 18) {
      let a = "我说let 字符串";
    
      welcome(); // 运行
      confirm.alert(a); // 运行
    } else {
      welcome = function () {
        alert("Greetings!");
      };
    }
    
    welcome(); // 不报错
    

    这样,welcome() 函数在整个脚本中都是可见的,而 a 变量则可以在 if 代码块内外访问,从而解决了您的问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月28日
  • 已采纳回答 4月20日
  • 创建了问题 4月20日

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上