她与晚风 发表于 2023-5-30 23:06:56

M方法中的隐式变量b不会往前提吗,为什么不输出undefined,反而报错

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>



    N();
    function N(){
      console.log('a: ' + a);//undefined
      var a = 10;
      console.log('a: ' + a);//10
    }

    M();
    function M(){
      console.log('b : ' + b)//报错
      b = 10;
    }
</script>
</head>
<body>
</body>
</html>

歌者文明清理员 发表于 2023-5-30 23:11:53

在函数M中,变量b并没有被声明,因此JavaScript将其视为未定义(undefined)的变量。在调用console.log('b : ' + b)时,解释器无法找到变量b,因此会抛出一个ReferenceError(引用错误)。和变量a不同,虽然在N()函数之前调用了console.log('a: ' + a),但是由于var a = 10是在console.log之后的语句,所以变量a已经被声明,并且在第二个console.log语句中赋值为10。这是JavaScript的变量提升机制。反过来,在函数M中,在为变量b赋值之前,必须先声明该变量。

isdkz 发表于 2023-5-30 23:12:00

这里面包含了JavaScript的两个主题:变量提升(Hoisting)和作用域。

在 JavaScript 中,函数和变量的声明会被提升到他们所在的作用域的顶部。这就是为什么在N函数中可以在变量a声明之前就使用它。在这个例子中,变量a的声明(但不是赋值)被提升,所以在赋值前, a的值是undefined 。

然而在M函数中,你试图访问一个还没有声明的变量b 。变量b不是一个声明的变量(比如使用var ,let ,const声明),它是一个隐式全局变量。在非严格模式下,尝试在赋值前引用这样的变量不会引发错误,而是将其视为undefined 。但是在严格模式下( "use strict"; ),这样做会引发 ReferenceError 错误。JavaScript推荐在使用变量之前明确声明它,以此来防止意外创建全局变量。

根据你的代码片段,我猜测可能是运行在严格模式下,这就是为什么尝试引用变量b会报错。如果你希望在M函数的开始就可以访问变量b ,你可以在顶部声明它,就像a一样。

这就是这段代码的执行方式:在N函数中, a在声明之前就被提升了,而在M函数中, b在声明之前没有被提升。

她与晚风 发表于 2023-5-31 01:12:34

isdkz 发表于 2023-5-30 23:12
这里面包含了JavaScript的两个主题:变量提升(Hoisting)和作用域。

在 JavaScript 中,函数和变量的声 ...

okok
页: [1]
查看完整版本: M方法中的隐式变量b不会往前提吗,为什么不输出undefined,反而报错