爱林可可可 发表于 2020-4-13 23:47:40

JS语法作用域问题求助

本帖最后由 爱林可可可 于 2020-4-13 23:49 编辑

请问:
1.为什么第一个两个console.log(a)输出的一个是函数a = 21 一个是变量a =1 (根据颜色也能看出来)
2.为什么第二个cosloe.log(a1)在if里面和外面输出的一个是 21 一个是 function a1(){ }呢?(为什么js没有报错)

4goodworld 发表于 2020-4-13 23:47:41

我个人的理解哟,因为也看不到js的内部编译器的效果,所以可谓是“想当然尔”
{
console.log(bb);//undefined
var bb=2;
console.log(bb);//2
}
我作了这个测试,发现效果是如此的
我推测
图2
function a(){};之前的鱼友也提到了,可以认为是var a = function();
根据变量声明会被提前的原则
我大胆猜测,可能
{
function a1(){};
a1=21;
console.log(a1);
}
console.log(a1);
可以转成
var a1=function();
{
a1=21;
console.log(a1);
}
console.log(a1);
可能有点绕,但我感觉就返回f a1(){} 就好像是正常的变量返回undefined的效果是一样的,一个function类型的变量被声明但没有初始化

shawnsui 发表于 2020-4-14 09:19:12

本帖最后由 shawnsui 于 2020-4-14 09:46 编辑

第一个问题:
       在 if 代码块中,function a(){} 相当于 var a = function(){};这样看起来,是不是就没那么绕了

第二个问题:
      
       同样的 var a1 = function(){};


这两个问题中,没有作用域的问题,只是有没有重新定义变量

爱林可可可 发表于 2020-4-14 10:15:21

shawnsui 发表于 2020-4-14 09:19
第一个问题:
       在 if 代码块中,function a(){} 相当于 var a = function(){};这样看起来,是不是 ...

按照您的解释 第一个是很好理解的 那为什么第二个a1 console.log(a1)在if内部和外部输出结果不一样呢

爱林可可可 发表于 2020-4-14 10:36:43

请问我这样理解可以吗
在第一个问题里面:
在 if 代码块中,function a(){} 相当于 var a = functiona(){} 是相当于重新定义了一个新的函数a 所以第一个console.log(a)是输出的就近的局部变量的函数a 所以会输出函数 a = 21
if外的console.log(a)就先会检索全局变量a 然后再去检索局部变量(函数a)所以优先输出的是全局变量 a = 1

在第二个问题里面:
第二个a1 同样也是如此 console.log(a1)检索不到全局变量a1 就去局部变量里面找 但是局部变量里的 a1 = 21写在 var a1 = function a1(){}的后面 只在局部变量里面生效 但是js只检测到了 var a1 = function a1(){}的这一行 所以就直接输出了 这样的话 在if 里面和外面进行console.log(a1) 输出结果才会有差异

wp231957 发表于 2020-4-14 10:42:00

爱林可可可 发表于 2020-4-14 10:36
请问我这样理解可以吗
在第一个问题里面:
在 if 代码块中,function a(){} 相当于 var a = functiona(){ ...

我其实对于你给函数名赋值这个事情很不理解没有意义的事情   没有讨论必要

shawnsui 发表于 2020-4-14 10:48:24

我给的答案有点误人子弟了,第二个问题,如果按照 var a1 = function(){}; 这样改,输出是不一样的,具体为什么我也不知道了

爱林可可可 发表于 2020-4-14 10:53:57

wp231957 发表于 2020-4-14 10:42
我其实对于你给函数名赋值这个事情很不理解没有意义的事情   没有讨论必要

主要这是网友问的一道题目呀 我就是想搞清楚 如果实在没意义我就跳过了算啦{:5_108:}

wp231957 发表于 2020-4-14 10:56:17

爱林可可可 发表于 2020-4-14 10:53
主要这是网友问的一道题目呀 我就是想搞清楚 如果实在没意义我就跳过了算啦

<body>
    <script>
      let a=10;
      function foo(){
            console.log("1:="+a);
            a++;
            console.log("2:="+a);
            //let a=20;   无法执行
            var a=20;    /*
                        1:=undefined
                        2:=NaN
                        4:=20
                        3:=10
                        */
            console.log("4:="+a);
      };
      foo();
      console.log("3:="+a);
    </script>
   <script>
      var b=10;
      function foo2(){
            console.log("11:="+b);
            b++;
            console.log("22:="+b);
            //let a=20;   无法执行
            var b=20;   
            console.log("44:="+b);
      };
      foo2();
      console.log("33:="+b);
      /*
      1:=undefined
      2:=NaN
      4:=20
      3:=10
      11:=undefined
      22:=NaN
      44:=20
      33:=10
      */
    </script>
</body>

sukiwhip 发表于 2020-4-14 11:27:44

本帖最后由 sukiwhip 于 2020-4-14 11:29 编辑

if 语句中使用函数声明会存在各种怪异,只是刚好你的浏览器表现出了其中一种情况,换别的浏览器(内核)行为又不一样了。
所以应该在 if 中使用函数表达式,而不是函数声明。

参考 https://www.zhihu.com/question/265381252/answer/875455178

爱林可可可 发表于 2020-4-14 18:45:56

4goodworld 发表于 2020-4-13 23:47
我个人的理解哟,因为也看不到js的内部编译器的效果,所以可谓是“想当然尔”

我作了这个测试,发现效果 ...

大概明白啦 谢谢!

爱林可可可 发表于 2020-4-14 18:56:17

wp231957 发表于 2020-4-14 10:56
let a=10;
      function foo(){
            console.log("1:="+a);


谢谢

爱林可可可 发表于 2020-4-14 18:57:32

shawnsui 发表于 2020-4-14 10:48
我给的答案有点误人子弟了,第二个问题,如果按照 var a1 = function(){}; 这样改,输出是不一样的,具体为 ...

谢谢!

shawnsui 发表于 2020-4-15 09:39:00

4goodworld 发表于 2020-4-13 23:47
我个人的理解哟,因为也看不到js的内部编译器的效果,所以可谓是“想当然尔”

我作了这个测试,发现效果 ...

感谢,又学到一个知识点:变量声明提前。

在网上找了一个比较详细的关于"变量声明提前"的博文,有兴趣的可以前往看一下 https://blog.csdn.net/zhumany_csdn/article/details/85260263
页: [1]
查看完整版本: JS语法作用域问题求助