前面的话

  尽管函数作用域是最常见的作用域单元,也是现行大多数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);//10

  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]());//5

  当然,可以通过函数传参,来保存每次循环的值

var a = [];
for(var i = 0; i < 5; i++){a[i] = (function(j){return function(){return j;}})(i);
}
console.log(a[0]());//0

  而使用let则更方便,由于let循环有一个重新赋值的过程,相当于保存了每一次循环时的值

var a = [];
for(let i = 0; i < 5; i++){a[i] = function(){return i;}
}
console.log(a[0]());//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 definedlet 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 ); // 3
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); // 2
}
console.log(a); //ReferenceError: a is not defined

  在ES6之前的环境中,可以使用try-catch语句达到上面代码的类似效果

try{throw 2;
}catch(a){console.log( a ); // 2
}
console.log( a ); //ReferenceError: a is not defined

//或者
try{throw undefined;
}catch(a){a = 2;console.log( a ); // 2
}
console.log( a ); //ReferenceError: a is not defined

转载于:https://www.cnblogs.com/xiaohuochai/p/5701287.html

深入理解javascript作用域系列第四篇——块作用域相关推荐

  1. 深入理解javascript作用域系列第三篇

    前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇--声明提升(hois ...

  2. 深入理解javascript函数系列第二篇——函数参数

    前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数.本文是深入理解javascript函数 ...

  3. javascript面向对象系列第三篇——实现继承的3种形式

    前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.开宗明义,继承是指在原有对象的基础上,略作修改,得到一个新的对象.javascript主要包括类式继承.原型继承和拷贝继承这三种 ...

  4. UR机器人装箱姿态_UR10 RG2机械臂手臂+RealsenseZR300 机器人手眼标定 系列第四篇

    UR10 RG2机械臂手臂+RealsenseZR300 机器人手眼标定 系列第四篇 发布时间:2018-09-18 17:43, 浏览次数:1180 , 标签: UR RG RealsenseZR ...

  5. 【JavaScript 教程系列第 10 篇】判断一个数是整数还是小数

    这是[JavaScript 教程系列第 10 篇],如果觉得有用的话,欢迎关注专栏. 思路 如果一个数是整数,那么 parseInt() 函数和 parseFloat() 函数的返回值是相同的,反之返 ...

  6. 【JavaScript 教程系列第 8 篇】什么是闰年?判断某一年是不是闰年

    这是[JavaScript 教程系列第 8 篇],如果觉得有用的话,欢迎关注专栏. 闰年分为 普通年:能被 4 整除且不能被 100 整除的是闰年. 世纪年:能被 400 整除的是闰年. 依据这两个判 ...

  7. 互联网大脑的情绪,智商和梦境-互联网神经学系列第四篇

    这是互联网神经学系列的第四篇文章"互联网大脑的情绪.智商和梦境,互联网神经心理学" 1.互联网神经心理学的提出 我们在互联网神经学系列的第三篇文章中详细介绍了互联网大脑的架构和运行 ...

  8. JavaScript高级程序设计 第四章---变量 作用域 内存

    第四章-变量 作用域 内存 关键字:变量 作用域 内存 本章内容 通过变量使用原始值与引用值 理解执行上下文 理解垃圾回收 4.1 原始值与引用值 ECMAScript 变量可以包含两种不同类型的数据 ...

  9. 深入理解DOM事件机制系列第四篇——事件模拟

    前面的话 事件是网页中某个特别的瞬间,经常由用户操作或通过其他浏览器功能来触发.但实际上,也可以使用javascript在任意时刻来触发特定的事件,而此时的事件就如同浏览器创建的事件一样.本文将详细介 ...

最新文章

  1. 互联网之父公开拍卖万维网源代码,3400万买下后发现居然有bug
  2. JavaScript实现找出一个数的质因数primeFactors算法(附完整源码)
  3. WCF系列之.net(3.0/3.5)Rest使用示例
  4. 如何解决ORA-12638: 身份证明检索失败错误
  5. PAT乙级 1029 旧键盘
  6. KANO模型,一个能解决你工作中90%烦恼的需求分析神器
  7. JavaScript和JQuery获取DIV的值
  8. 【优化算法】材料生成算法 (MGA)【含Matlab源码 209期】
  9. ADOBE CS3 序列号
  10. 安全bios手册(5)
  11. 单片机基础:MCS-51单片机的硬件结构(附硬件结构框图)
  12. arduiono电子音乐代码_使用Word2003的EQ域代码制作音乐简谱
  13. ValueError: Input 0 of node ... was passed float from ... incompatible with expected float_ref.
  14. 详细剖析市面手机基带/射频/处理器配置, 比较各家手机性能
  15. 利用正则截取匹配的字符串前后内容同
  16. 三栏布局的七种实现方式
  17. 说一说TS码流里面的PCR
  18. 英语书写_手写印刷体
  19. memset函数的赋值
  20. 服务器芯片制冷,新一代元件级热管式自然冷却液冷技术的解决方案

热门文章

  1. 汉语是世界上唯一一种面向对象的高级语言
  2. springBoot 打war包 程序包com.sun.istack.internal不存在的问题
  3. Exchange 2013sp1邮件系统部署-(七)
  4. 构建布局良好的windows程序
  5. 《潮流时装设计——世界顶级时装CAD制板技巧》——1.6 服装生产中各部位国际代号...
  6. 5 Best User Interface Design Pattern Libraries
  7. 例说DNS递归/迭代名称解析原理
  8. 磨刀不误砍柴功:App开发者必备之8大利器
  9. 使用 EOLINKER 进行接口测试的最佳路径 (下)
  10. 将新主要功能部署到生产时要考虑的5件事情