ES6中的块级作用域与函数声明

首先,在ES5的标准中,函数是不能在块级作用域中声明的。

if(true){
    function foo(){}
}
try{
    function foo(){}
} catch(e){
    
}

也就是说类似以上两种情况在ES5中都是非法的。然而,浏览器为了兼容旧代码所以并没有遵守这一规定。所以上面的代码在浏览器中运行并不会出错。

而在ES6的标准中引入了块级作用域,也确定了函数是能够被声明在块级作用域内的。同时还规定了,在块级作用域中声明的函数类似于使用let声明的变量,只能在块级作用域内有效

function foo(){console.log('Hello');}

(function (){
    if(false){
        function foo(){console.log('World');}
    }
    foo();
}());

上述代码若在ES5中运行,则会输出"World",原因则是因为发生了函数提升。即真正执行的代码如下,

function foo(){console.log('Hello');}

(function (){
    function foo(){console.log('World');}
    if(false){
        
    }
    foo();
}());

function foo(){console.log('Hello');}

(function (){
    if(false){
        function foo(){console.log('World');}
    }
    foo();
}());

但若是按ES6的标准,上面的代码应该输出的是"Hello",这样也是符合直觉的一个结果。因为按照前文的说法,声明的在if语句中的函数应该无法影响外部的作用域。

但是运行结果却让人大跌眼镜,

在这里插入图片描述
那么问题出在哪儿呢?原因还是出在对老代码的兼容性上,所以实现跟标准还是存在着出入。

  • 允许在块级作用域内声明函数。
  • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
  • 同时,函数声明还会提升到所在的块级作用域的头部。

那么按照这三条规则来看,上面的代码应该是下面的样子的,

function foo(){console.log('Hello');}

(function (){
    var foo = undefined;
    if(false){
        function foo(){console.log('World');}
    }
    foo();
}());

所以,这样就能理解为啥报错会提示foo不是一个函数了,因为它是一个undefined

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值