问答

解释一下这段代码

作者:admin 2021-05-05 我要评论

function f() { console.log(1);}(function() { if(false) { function f() { console.log(2); } } f();})(); ### mdn上这么说的 理论上function name() {} 是整...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)
function f() {
    console.log(1);
}
(function() {
    if(false) {
        function f() {
            console.log(2);
        }
    }
    f();
})();
###

mdn上这么说的
理论上function name() {} 是整个函数提升的
但是有条件的提升在各个浏览器上表现可能不一样,也就是说,这个带有条件的时候,提升会被单独处理,也就是说 可能按照变量的方式处理了。
https://developer.mozilla.org...

###

楼上的解释有问题呀,下面的代码是没问题的:

function foo() {
    console.log(1);
}
(function() {
    if(false) {
        function f() {
            console.log(2);
        }
    }
    foo();
})();
###

js文件是一个文本文件。当它被符合ECMA-262标准实现的引擎(编译器)读取时,会经历以下阶段:
以文本形式读取 => 词法分析(Tokenization、Parsing等) => 编译(Compilation) => 优化(Optimization)
然后才会以机器可识别的语言执行。

ECMA-262标准中,以function关键字进行的函数申明中的函数名变量将得到变量提升。
因此,当在闭包函数中以function关键字申明变量f时,变量f将会得到变量提升。而变量f的作用域为闭包函数内,所以此时相当于在闭包函数内执行了var f;。即只申请了变量名及空间,但未进行任何赋值
当运行至if (false)语句时,由于此时并未进入条件分支,所以并未对f变量进行赋值。当对f以函数方式调用执行时,因为f未进行任何赋值,所以是无法调用成功的。
至于闭包外的f函数,因为其作用域在闭包外,如果闭包函数内并未申明f变量,那么会根据标准从词法上下文中查找f,那么就会找到闭包外的f变量;但问题中,在闭包函数内同时申明了变量f,因此只会使用闭包内的变量f,而恰巧这个变量f没有进行赋值,所以在闭包内以函数方式调用f,是行不通的。

###

自执行匿名函数,有自己的作用域,因此访问不到外部的f函数,在内部调用的时候会报undefined

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 解释一下这段代码

    解释一下这段代码

  • vue 计算属性修改data为什么报“Unexpe

    vue 计算属性修改data为什么报“Unexpe

  • 诚心提问,大家到底怎么做移动端适配

    诚心提问,大家到底怎么做移动端适配

  • 怎样设置echarts的环形图中间显示文字

    怎样设置echarts的环形图中间显示文字

腾讯云代理商
海外云服务器