深入理解javascript作用域系列第四篇——块作用域
前面的话
尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀、简洁的代码,比如块作用域。随着ES6的推广,块作用域也将用得越来越广泛。本文是深入理解javascript作用域系列第四篇——块作用域
let
for (var i= 0; i<10; i++) {
console.log(i);
}
上面这段是很熟悉的循环代码,通常是因为只想在for循环内部的上下文中使用变量i,但实际上i可以在全局作用域中访问,污染了整个作用域
for (var i= 0; i<10; i++) {
console.log(i);
}
console.log(i);//
ES6改变了现状,引入了新的let关键字,提供了除var以外的另一种变量声明方式。let关键字可以将变量绑定到所在的任意作用域中(通常是{...}内部),实现块作用域
{
let i = 1;
};
console.log(i);//ReferenceError: i is not defined
块级作用域实际上可以替代立即执行匿名函数(IIFE)
(function(){
var i = 1;
})();
console.log(i);//ReferenceError: i is not defined
如果将文章最开始那段for循环的代码中变量i用let声明,将会避免作用域污染问题
for (let i= 0; i<10; i++) {
console.log(i);
}
console.log(i);////ReferenceError: i is not defined
for循环头部的let不仅将i绑定到了for循环的块中,事实上它将其重新绑定到了循环的每一个迭代中,确保使用上一个循环迭代结束时的值重新进行赋值
//与上一段代码等价
{
let j;
for (j=0; j<10; j++) {
let i = j; //每个迭代重新绑定
console.log( i );
}
}
循环
下面代码中,由于闭包只能取得包含函数中的任何变量的最后一个值,所以控制台输出5,而不是0
var a = [];
for(var i = 0; i < 5; i++){
a[i] = function(){
return i;
}
}
console.log(a[0]());//
当然,可以通过函数传参,来保存每次循环的值
var a = [];
for(var i = 0; i < 5; i++){
a[i] = (function(j){
return function(){
return j;
}
})(i);
}
console.log(a[0]());//
而使用let则更方便,由于let循环有一个重新赋值的过程,相当于保存了每一次循环时的值
var a = [];
for(let i = 0; i < 5; i++){
a[i] = function(){
return i;
}
}
console.log(a[0]());//
重复声明
let不允许在相同作用域内,重复声明同一个变量
{
let a = 10;
var a = 1;//SyntaxError: Unexpected identifier
}
{
let a = 10;
let a = 1;//SyntaxError: Unexpected identifier
}
提升
使用let进行的声明不会在块作用域中进行提升
{
console.log(i);//ReferenceError: i is not defined
let i = 1;
};
const
除了let以外,ES6还引入了const,同样可以用来创建块作用域变量,但其值是固定的(常量)。之后任何试图修改值的操作都会引起错误
if (true) {
var a = 2;
const b = 3;
a = 3;
b = 4;// TypeError: Assignment to constant variable
}
console.log( a ); //
console.log( b ); // ReferenceError: b is not defined
const声明的常量,也与let一样不可重复声明
const message = "Goodbye!";
const message = "Goodbye!";//SyntaxError: Identifier 'message' has already been declared
try
try-catch语句的一个常见用途是创建块级作用域,其中声明的变量仅仅在catch内部有效
{
let a = 2;
console.log(a); //
}
console.log(a); //ReferenceError: a is not defined
在ES6之前的环境中,可以使用try-catch语句达到上面代码的类似效果
try{
throw 2;
}catch(a){
console.log( a ); //
}
console.log( a ); //ReferenceError: a is not defined
//或者
try{
throw undefined;
}catch(a){
a = 2;
console.log( a ); //
}
console.log( a ); //ReferenceError: a is not defined
深入理解javascript作用域系列第四篇——块作用域的更多相关文章
- 深入理解javascript函数系列第四篇——ES6函数扩展
× 目录 [1]参数默认值 [2]rest参数 [3]扩展运算符[4]箭头函数 前面的话 ES6标准关于函数扩展部分,主要涉及以下四个方面:参数默认值.rest参数.扩展运算符和箭头函数 参数默认值 ...
- 深入理解javascript作用域系列第四篇
前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...
- 深入理解javascript函数系列第三篇——属性和方法
× 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...
- 深入理解javascript函数系列第三篇
前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数 ...
- javascript面向对象系列第四篇——选项卡的实现
前面的话 面向对象的应用并非只是读几本书那么容易,需要有大量的工程实践做基础才能真正理解并学会使用它.本文将用面向对象的技术来制作一个简单的选项卡 图示说明 由图示结果看到,这是一个非常简单的选项卡. ...
- javascript面向对象系列第四篇——OOP中的常见概念
前面的话 面向对象描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法.本文将从理论层面,介绍javascript面向对象程序程序(OOP)中一些常见的概念 对象 所谓对象,本质 ...
- 深入理解javascript对象系列第三篇——神秘的属性描述符
× 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...
- javascript运动系列第四篇——抖动
× 目录 [1]原理介绍 [2]代码实现 [3]实例应用 前面的话 在运动系列中,前面分别介绍了匀速运动.变速运动和曲线运动.下面介绍一种特殊的运动形式——抖动 原理介绍 抖动其实是往复运动的一种特殊 ...
- javascript动画系列第四篇——拖拽改变元素大小
× 目录 [1]原理简介 [2]范围圈定 [3]大小改变[4]代码优化 前面的话 拖拽可以让元素移动,也可以改变元素大小.本文将详细介绍拖拽改变元素大小的效果实现 原理简介 拖拽让元素移动,是改变定位 ...
随机推荐
- 在wifi状态下没有数据线,链接手机调试
因为不知道是手机的问题还是数据线的问题,经常链接不上adb 所以找了一下wifi情况下,无线跟eclipse链接调试 第一步,首先你需要在你的手机上安装一个终端模拟器工具 第二步,在终端里输入(需要r ...
- 安装 webpack
安装 webpack看好webpack 对自动压缩和文件名自动md5更名,可解决客户端缓存问题.我的安装环境为 centos linux,root用户 1.安装Node及NPM.到NodeJS官网安装 ...
- Linux内核--网络栈实现分析(十一)--驱动程序层(下)
本文分析基于Linux Kernel 1.2.13 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7555870 更多请查看专栏,地 ...
- 练习1-16:修改打印最长文本行的程序的主程序main,使之可以打印任意长度的输入行的长度,并尽可能多地打印文本(C程序设计语言 第2版)
该书英文配套答案 Answer to Exercise -, page Revise the main routine of the longest-line program so it will c ...
- C语言标准定义的32个关键字
关键字 意 义 auto 声明自动变量,缺省时编译器一般默认为auto int ...
- EBS excel模板xml publisher开发
前提: BI publisher下载地址: http://www.oracle.com/technetwork/middleware/bi-publisher/downloads/index.html ...
- winform 子报表
public void BindReport(string _invno,string _type) { if (!Is_Has_Express_No(_inv ...
- Icident event 分析
现象 备库中断,显示如下错误 Connect_Retry: 60 Master_Log_File: mysql-bin.000185 Read_Master_Log_Pos: 308647804 Re ...
- ORACLE EXP/IMP的使用详解
导入/导出是ORACLE幸存的最古老的两个命令行工具,其实我从来不认为Exp/Imp 是一种好的备份方式,正确的说法是Exp/Imp只能是一个好的转储工具,特别是在小型数据库的转储,表空间的迁移,表的 ...
- Nightmare基于phantomjs的自动化测试套件
今天将介绍一款自动化测试套件名叫nightmare,他是一个基于phantomjs的测试框架,一个基于phantomjs之上为测试应用封装的一套high level API.其API以goto, re ...