ES6中块级作用域下的函数声明
背景
因为ES5的时候没有块级作用域,所以ES5规定不能再if这样的块中声明函数,但是为了兼容各大浏览器并没有严格遵守这条规定。
ES6的时候引入了块级作用域,规定在块级作用域中声明函数就相当于使用let来声明变量一样。但是又因为浏览器端的兼容问题,标准中说明浏览器端的实现可以不完全遵守,有自己的行为,如下:
- 允许在块级作用域内声明函数。
- 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
- 同时,函数声明还会提升到所在的块级作用域的头部。
if (false) {function a() {}
}
console.log(a);
上面输出 undefined
这表明了上面两条,一个是允许在块级作用域内声明函数,一个是块级作用域内声明类似于var。
if (true) {console.log(a);function a() {}
}
输出函数a,这表明了第三条:函数声明会提升到所在块级作用域的头部。
问题和信息
上面现有的理论并不够解释下面的现象:
var a;{a = 5;function a() {}a = 0;console.log(a);
}
console.log(a);
chrome最新版输出的是:第一个console输出的是0
,第二个console输出的是5
。
先陈述下依据已知的三条理论得出上面代码几个不合理的现象:
- 首先稍微变通就知道如下代码:
{function a() {}
}console.log(a);
这里打印了a是一个函数,穿透了块级作用域。上面并没有解释这种现象。
a = 0;
的赋值并没有影响到块外部的a。
解释上面两个问题,还需要额外的信息(信息来自stackoverflow高赞回答,原文在参考链接中):
function enclosing() {{function compat() {}}
}// works the same asfunction enclosing() {var compat₀ = undefined; // function-scoped{let compat₁ = function compat() {}; // block-scopedcompat₀ = compat₁;}
}
上面对块中的函数声明引入的额外的概念,更加清晰明了的解释了底层做了什么。
首先额外引入的信息本身也存在一些问题。少了函数会提升到当前块作用域顶部,我认为应该如下修改:
function enclosing() {var compat₀ = undefined; // function-scoped{function compat() {}let compat₁ = compat; // block-scopedcompat₀ = compat₁;}
}
这样就修复了没有函数提升的问题。
猜想
根据额外补充的知识加上自己的想象力得到如下结果:
var a₀;{// 这部分被提升function a() {}let a₁ = a;a₀ = a;// 这部分被提升ENDa₀ = 5;a₁ = 0;console.log(a₁);
}
console.log(a₀);
a₀ 和 a₁ 都是a在不同位置的不同分身。
参考
- let 和 const 命令
- What are the precise semantics of block-level functions in ES6?
ES6中块级作用域下的函数声明相关推荐
- [ES6] 细化ES6之 -- 块级作用域
所谓的块级作用域,可能是一个{},一个代码块,一句话 let关键字 let 与 var 区别 区别 var let 变量提升 有 无 作用域 全局作用域.函数作用域 全局作用域.函数作用域和块级作用域 ...
- es6 ie不兼容 函数_ES6:什么是块级作用域?
在 ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景. 我们先来看一下下面这种情况:内层变量可能会覆盖外层变量. var txt = '外层变量-->你好呀';func ...
- es6中的块级作用域
块级作用域 凡是带{}都是块级作用域,if(){} for(){} 对象{} 1.在块级作用域下,var 和function跟在window下一样, function有个特殊的一点,在块级作用域下会提 ...
- ES6 块级作用域详解
什么是块级作用域 ES6 中新增了块级作用域.块作用域由 { } 包括,if 语句和 for 语句里面的 { } 也属于块作用域. 为什么需要块级作用域 第一种场景:内部变量会覆盖外部变量 var t ...
- 搭建Babel运行环境,Traceur ES6模板,块级作用域,let和const命令
搭建Babel运行环境 Babel(http://babeljs.io/)可用于将使用ES6语法的脚本转化为ES5语法的脚本,基本功能的安装步骤如下: 1.安装node解释器和npm包管理工具 2.安 ...
- javascript中作用域、全局作用域、局部作用域、隐式全局变量、块级作用域、作用域链、预解析
作用域 作用域指的是代码的作用范围,按照作用域划分变量可分为全局变量和局部变量:作用域可分为: 全局作用域: 指全局变量作用的范围:全局变量指的是通过var在函数外面声明的变量,在js中任何位置都可以 ...
- 块级作用域和函数作用域
函数作用域与块级作用域 函数作用域:在函数内部声明的变量只能影响到变量所在函数体本身,无法从外部对函数内部的变量进行调用,被称为'函数作用域' 块级作用域:ES6 引入了 let 和 const 关键 ...
- ES6-2 块级作用域与嵌套、let、暂行性死区
注意,写在开头 function test(x = 1) {var x // 不报错console.log(x) } function test1(x = 1) {let x = 10 // 报错co ...
- java区块作用域_ES6-let、const和块级作用域
1.介绍 总的来说,ES6是在ES2015的基础上改变了一些书写方式,开放了更多API,这样做的目的最终还是为了贴合实际开发的需要.如果说一门编程语言的诞生是天才的构思和实现,那它的发展无疑就是不断填 ...
最新文章
- CentOS 6虚拟机安装
- 4月机器学习热文出炉,这10篇文章你读了吗?
- 深度:生成模型(GAN)的最新进展
- 使用ilmerge实现.net程序静态链接
- 使用jclouds在S3上分段上传
- CSS中越界问题经典解决方案
- PS特效:图像碎片化
- 【clickhouse】clickhouse 表引擎 之 AggregatingMergeTree
- 翻译: 构建基于卡尔曼滤波器的 IMU 用速度数据改进 IMU 姿态估计
- ssm图书馆管理系统
- matlab 广义特征,特征值 特征向量 广义特征值 matlab
- hdu 1880 魔咒词典 (字符串哈希)
- vue 免费个人博客模板
- 春天里,阳光下,无限的哀思和想念
- 计算机数据备份到u盘,技术给你说Win10系统怎么把数据备份到U盘的完全处理手段...
- 开始使用 Elasticsearch (1)
- ipv6内网穿透,有ipv6地址外网无法访问
- c语言windows画五角星,C/C++画一个巨型五角星
- MATLAB科学绘图-MATLAB画图技巧与实例(一):常用函数
- 我们为什么这么拼?(转载自微信)