前言
我们都知道es6引入了块级作用域,今早看群有小伙伴认为没有let const就不存在块级作用域结果被教做人了....我突然发现我好像也不是很明白这部分所以研究了一下,主要还是函数受到的影响这块.
什么是块级作用域?
看看mdn怎么说?
块语句(或其他语言的复合语句)用于组合零个或多个语句。该块由一对大括号界定,可以是labelled:
可能不是很清楚,人话就是:
在一个代码块{}中定义的变量,常量,函数,类(let,const,function,class)外部不能访问,这个特性在if,for....等等只要带{}的语句中都存在
比如:
{
let a = 111
}
console.log(a);// a is not defined
但是有两个特殊的家伙比较难搞,就是var function.
还是先看看mdn怎么说:
使用let和 const
我们讨论的重点来了---函数!
这个例子我觉得不好,不能说明一些问题.因为我们把代码放下面还是会执行的.
{
function foo(location) {
console.log('foo is called ' + location);
}
foo('inside'); // 正常工作并且打印 'foo is called inside'
}
foo('outside'); // 正常工作并且打印 'foo is called outside'
es6中是不允许块作用域中声明的函数被外部访问的但是这又是为什么呢?
{
function log (){
console.log("打印了");
}
}
log()//打印了
我们发现还是正常打印了,这是因为浏览器并完全遵守es6.我们换node环境试一下结果也可以....那么严格模式呢?
"use strict";
// 严格模式下
{
function foo(location) {
console.log('foo is called ' + location);
}
foo('inside'); // 正常工作并且打印 'foo is called inside'
}
foo('outside'); //foo is not defined
终于报错了...
接下来分享一个知乎看见的例子
大家知道答案是什么吗?
为什么会这样呢? 记住这三句(浏览器遵循的es6标准,来自知乎老哥的原文)
- 允许在块级作用域内声明函数
- 函数声明(函数名称) 类似于 var,即会提升到全局作用域或函数作用域的头部
- 同时,函数声明(函数整体) 还会提升到所在的块级作用域的头部
根据刚才说的第二句话,由于函数声明类似于 var ,所以程序会相当于这个样子:
再根据刚才说的第三句话,函数声明(函数整体) 还会提升到所在的块级作用域的头部.程序会相当于这个样子:
所以,程序运行的结果会是:
回到源程序:
注意!这都是在浏览器的非严格模式下,如果是node或者浏览器的严格模式下函数声明类似于let
我们看看node的严格模式下
"use strict";
{
function foo(location) {
console.log('foo is called ' + location);
}
}
foo('outside'); // foo is not defined
成功报错! 最后总结一下,函数在浏览器环境下的块作用域中不会被完全限制在块中,而是被限制在块作用域内以及块代码下部.外部访问的话相当于一个var的提升而不是函数整体
参考资料: