摘要:尽管如此,由于块作用域的缘故,这段代码还是能够安全地运行。块作用域的显式声明如何避免上述问题呢答案是利用额外的一对大括号来做块作用域的显式声明。
ES2015已经定稿一年多了,想必大家早就用上let和const来充分利用块作用域的优势了吧?那么,你们知道块作用域都是怎么声明的吗?
在各种教程资料的例子里,块作用域都是出现在for(……){……}/if(……){……}/while(……){……}这些语句里的,那你有没有想过,块作用域其实跟这些逻辑控制语句完全没有关系?
前置知识本文需要有块作用域以及let / const相关知识,如有欠缺,请看这里。
块作用域的标识块作用域的标识其实是那一对大括号{},换句话说,我们不需要任何逻辑控制语句就可以直接使用大括号来创建块作用域:
var a = 2; { let a = 3; } console.log(a); // 输出2块作用域的隐式声明
相信大家一般都不会直接用大括号来创建块作用域,而是像下面这个例子来使用:
var a = 2; var b = 2; var c = 0; if (a === b) { let c = 2; a ++; b -= c; } console.log(a); // 3 console.log(b); // 0
你可能注意到,这段代码里定义了两个变量c,这有时并不是故意重复起名为c,而是前面一大堆代码,根本不知道变量名c已经被用掉了。尽管如此,由于块作用域的缘故,这段代码还是能够安全地运行。
但如果这段代码由别人接手,而他又急于改需求呢,那很可能就会出现以下这种情况:
var a = 2; var b = 2; var c = 0; if (a === b) { let c = 2; a ++; } b -= c; console.log(a); // 3 console.log(b); // 2
需求是这样改的:不需要判断a === b就执行b -= c;了。此时,这段代码在运行时也不会报错(因为前面早已定义有了一个同名变量c),但结果却出错了,而且往往这种错误还不容易发现。
块作用域的显式声明如何避免上述问题呢?答案是:利用额外的一对大括号来做块作用域的显式声明。
我们试着用块作用域的显式声明来修改上述代码:
var a = 2; var b = 2; var c = 0; if (a === b) { { // 使用大括号来包裹住块作用域变量相关的代码块 let c = 2; b -= c; } a ++; // 操作的都是块作用域外部就定义好的变量,剔除在大括号以外 } console.log(a); // 3 console.log(b); // 0
看着有点别扭是吧?没关系,我们看看按需求修改后的代码:
var a = 2; var b = 2; var c = 0; if (a === b) { a ++; } { let c = 2; b -= c; } console.log(a); // 3 console.log(b); // 0
duang!
爸爸妈妈再也不用担心我重构代码的时候出一大堆bug了!
总结块作用域的显式声明实际上是主动分隔开接受块作用域管理的let / const变量和不接受块作用域管理的var变量,从而帮助我们在重构代码时,能更轻松、更放心地挪动代码。
本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。
原文地址:https://segmentfault.com/a/1190000007639527
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/91171.html
摘要:提供了同时解决这两个问题的方案以上这种模式称为立即执行函数表达式。块作用域不应该完全作为函数作用域的替代方案,两种功能应该同时存在。 函数作用域 为了隐藏内部实现,可以通过在任意代码片段外部添加包装函数,但是这并不理想,因为必须声明一个具名函数,意味着这个函数名称本身会污染函数所在的作用域;同时必须通过显式地调用函数才能运行其中的代码。 *:区分函数声明和表达式最简单的方法是看func...
摘要:块级作用域中的块级作用域很有可能导致局部变量覆盖全局变量或者局部变量泄露成全局变量。也就是局部变量与全局变量不会打架块级作用域的出现,实际上使得获得广泛应用的立即执行匿名函数不再必要了。 let 和 const命令 1.let 命令 基本用法 语法类似 var,但是所声明的变量,只在 let 命令所在的代码块内有效。 在 for 循环中,就非常适合使用 let 声明变量。 var a...
摘要:大家好,我从今天开始就会正式讲的语法方面。变量中的变量一般使用来声明的不在本教程讨论范围内,可以用来定义任何种类的变量,如果只对变量进行了定义而没有赋值,这样变量会默认为。 大家好,我从今天开始就会正式讲javascript的语法方面。变量 js中的变量一般使用var来声明(es6的let不在本教程讨论范围内),可以用来定义任何种类的变量,如果只对变量进行了定义而没有赋值,这样变量会默...
摘要:大家好,我从今天开始就会正式讲的语法方面。变量中的变量一般使用来声明的不在本教程讨论范围内,可以用来定义任何种类的变量,如果只对变量进行了定义而没有赋值,这样变量会默认为。 大家好,我从今天开始就会正式讲javascript的语法方面。变量 js中的变量一般使用var来声明(es6的let不在本教程讨论范围内),可以用来定义任何种类的变量,如果只对变量进行了定义而没有赋值,这样变量会默...
摘要:全局作用域在任何函数块或模块范围之外定义的变量具有全局作用域。的局部函数作用域是函数的词法作用域。作用域链每个作用域都有一个指向父作用域的链接。当使用变量时,会向下查看作用域链,直到它找到所请求的变量或者到达全局作用域即作用域链的末尾。 一网打尽 JavaScript 的作用域 翻译:疯狂的技术宅https://medium.freecodecamp.o...-javascript...
阅读 1448·2021-11-25 09:43
阅读 2047·2021-07-26 23:38
阅读 752·2019-08-30 15:53
阅读 2290·2019-08-30 15:43
阅读 1184·2019-08-29 18:40
阅读 1982·2019-08-26 13:28
阅读 1987·2019-08-23 18:20
阅读 556·2019-08-23 15:07