鱼C论坛

 找回密码
 立即注册
查看: 4167|回复: 13

[已解决]JS语法作用域问题求助

[复制链接]
发表于 2020-4-13 23:47:40 | 显示全部楼层 |阅读模式
5鱼币
本帖最后由 爱林可可可 于 2020-4-13 23:49 编辑

请问:
1.为什么第一个两个console.log(a)输出的一个是函数a = 21 一个是变量a =1 (根据颜色也能看出来)
2.为什么第二个cosloe.log(a1)在if里面和外面输出的一个是 21 一个是 function a1(){ }呢?(为什么js没有报错)
最佳答案
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类型的变量被声明但没有初始化

两个a

两个a

两个a的输出结果

两个a的输出结果

两个a1

两个a1

两个a1的输出结果

两个a1的输出结果

为什么圈圈内的a1没有报错

为什么圈圈内的a1没有报错

最佳答案

查看完整内容

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

使用道具 举报

发表于 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类型的变量被声明但没有初始化
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-14 09:19:12 | 显示全部楼层
本帖最后由 shawnsui 于 2020-4-14 09:46 编辑

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

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


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

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-14 10:15:21 | 显示全部楼层
shawnsui 发表于 2020-4-14 09:19
第一个问题:
       在 if 代码块中,function a(){} 相当于 var a = function(){};  这样看起来,是不是 ...

按照您的解释 第一个是很好理解的 那为什么第二个a1 console.log(a1)在if内部和外部输出结果不一样呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 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) 输出结果才会有差异
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

我其实对于你给函数名赋值这个事情很不理解  没有意义的事情   没有讨论必要
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-14 10:48:24 | 显示全部楼层
我给的答案有点误人子弟了,第二个问题,如果按照 var a1 = function(){}; 这样改,输出是不一样的,具体为什么我也不知道了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-14 10:53:57 | 显示全部楼层
wp231957 发表于 2020-4-14 10:42
我其实对于你给函数名赋值这个事情很不理解  没有意义的事情   没有讨论必要

主要这是网友问的一道题目呀 我就是想搞清楚 如果实在没意义我就跳过了算啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-14 11:27:44 | 显示全部楼层
本帖最后由 sukiwhip 于 2020-4-14 11:29 编辑

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

参考 https://www.zhihu.com/question/265381252/answer/875455178
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

大概明白啦 谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-14 18:56:17 | 显示全部楼层
wp231957 发表于 2020-4-14 10:56
let a=10;
        function foo(){
            console.log("1:="+a);

谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

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

在网上找了一个比较详细的关于"变量声明提前"的博文,有兴趣的可以前往看一下 https://blog.csdn.net/zhumany_csdn/article/details/85260263

评分

参与人数 1鱼币 +1 收起 理由
4goodworld + 1 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 08:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表