js中的块级作用域
概述
函数是js中最常见的作用域单元, 声明在一个函数内部的变量或函数会在所处的作用域中隐藏起来, 这是有意为之的非常好的设计原则.
但是随着js的发展, 我们有了某个代码块(通常指{..}内部)隐藏变量或函数的需求, 这就是块级作用域的由来.
下面是不用es6实现块级作用域的三种方法, 供以后开发时参考, 相信对其他人也有用.
IIFE
IIFE, 即立即执行函数, 用一个函数作用域(闭包)来模拟块级作用域.示例如下:
//es6中的块级作用域
{let a = 1;
console.log(a);}
console.log(a); //ReferenceError
//IIFE实现
(function() {
var a = 1;
console.log(a);
})();
console.log(a); //Undefined
可以看到, 由于变量提升, a不再是未初始化, 而是未定义. 这是使用IIFE不好的一方面, 但还可以接受. 另一方面由于闭包拥有很多不好的特性, 比如this指向改变啊, return,break和continue发生变化啊, 内存泄漏问题啊等等, 所以IIFE并不是一个普适的方案.
throw
从es3开始, js中就已经定义了一种块级作用域, 它就是throw函数. 示例如下:
//es6中的块级作用域
{let a = 1;
console.log(a);}
console.log(a); //ReferenceError
//throw函数实现
{
try {
throw undefined;
} catch(a) {
a = 2;
console.log(a);
}
}
console.log(a); //ReferenceError
之前我在看别人的代码的时候觉得用throw好像很高级, 可能是为了实现块级作用域吧.
当有多个变量时, 我们一般不用a, 而是用err123456等.
优雅的方案
如果用babel编译一下如上代码, 会发现编译出来的es5与上面的方案都不同, 它是这么编译的.
//es6中的块级作用域1
{let a = 1;
console.log(a);}
console.log(a); //ReferenceError
//babel编译1
"use strict";
{
var _a = 1;
console.log(_a);
}
console.log(a); //ReferenceError
//es6中的块级作用域2
{let a = 1;
console.log(a);
let _a = 2;
console.log(_a);
}
console.log(a);
console.log(_a);
//babel编译2
"use strict";
{
var _a2 = 1;
console.log(_a2);
var _a3 = 2;
console.log(_a3);
}
console.log(a);
console.log(_a);
哈哈, 是不是很优雅? 虽然会在全局初始化_a等变量, 但是没有太大的问题.
js中的块级作用域的更多相关文章
- 一个经典的js中关于块级作用域和声明提升的问题
function functions(flag) { if (flag) { function getValue() { return 'a'; } } else { function getValu ...
- JS中的块级作用域,var、let、const三者的区别
1. 块作用域{ } <script type="text/javascript"> { var a = 1; console.log(a); // 1 } conso ...
- 可怜的js居然没有块级作用域
js中在一个函数中定义一个for循环:for(var i=0;i<5;i++) 其中的i并不会随着for循环的结束就销毁,i会一直存在该函数中,这就是js和其他语言的区别,也就是js没有块级作用 ...
- javascript中模仿块级作用域
学过 javascript 的都知道 javascript 里面没有块级作用域的概念,这就意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,看下面的例子: function outPu ...
- es6中添加块级作用域的目的
原本只有函数作用域和全局作用域两种,这就导致出现很多不方便的地方: 1)for循环问题:在看js高程的时候,纠结在第七章好久,就是一个这样的实例 function createFunctions(){ ...
- Javascript中没有块级作用域(模仿)
在C/C++中,由花括号封闭的代码块都有自己的作用域,也就是块级作用域(私有作用域).而在javascript中则没有块级作用域,首先来看一段代码: function test(){ for(var ...
- JavaScript的作用;JS常见的三种对话框;==和===的区别;函数内部参数数组arguments在函数内部打印实参;JS的误区:没有块级作用域
JS:客户端(浏览器)脚本语言 弱类型 基于原型 事件驱动 不需要编译(直接运行) JS的作用:表单验证,减轻服务端的压力 添加页面动画效果 动态更改页面内容 Ajax网络请求 (一)常见的对 ...
- Javascript高级编程学习笔记(25)—— 函数表达式(3)模仿块级作用域
昨天写了闭包 今天就来聊聊块级作用域的事情 在绝大多数编程语言中,都有块级作用域这个概念 什么是块级作用域呢? 前面我们在刚开始讲的时候说过,JS中的大括号(不在赋值运算符的后面)表示代码块 块级作用 ...
- 你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域
原文:你不知道的js系列 在第(二)节中提到的,标识符在作用域中声明,这些作用域就像是一个容器,一个嵌套一个,这个嵌套关系是在代码编写时定义的. 那么到底是什么产生了一个新的作用域,只有函数能做到 ...
随机推荐
- 剑指offer例题——链表中倒数第K个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 编程过程 此处采用两个指针依次后移的方法来求解,首先,用一个指针移到第k个位置,之后将第二个指针放在第一位,与第二个指针一同移动,当第二个指针移动 ...
- php一次性大量数据入库解决方法
当有业务需求需要一次性循环n条数据,插入或更新数据库时,如果单纯的循环,插入/更新,会消耗太多的数据库资源 一下是一种简单的解决方案 数据库的insert 是可以批量更新的,当有大量数据循环i ...
- python命名规则
1 包.模块的命名规则:全部以小写字母形式来命名.比如:import random 2 类.对象的命名规则:类是每个单词的首字母要大写,其他字母小写比如:class MyFamily: ,类的私有属性 ...
- 数据库常用操作(mysql)
创建 create database 库名 create table 表名(列名 type(varchar(size),int(size),decimal(size,d))) "size&q ...
- 22. Generate Parentheses产生所有匹配括号的方案
[抄题]: Given n pairs of parentheses, write a function to generate all combinations of well-formed par ...
- Android Studio 减小项目文件夹的大小和.gitignore文件配置
Build --> Clean Project 可以清理出很大一部分的空间 手动删除以下文件或者目录 Dir : ProjectFolder/buildDir : ProjectFolder/a ...
- android nostra13
nostra13的ImageLoader可以让图片能在异步加载更加流畅,可以显示大量图片,在拖动ListView的时候不会出现卡的现象.可以实现ListView的图片加载.GridView的图片加载. ...
- RNA提取和建库流程对mRNA-Seq的影响
RNA提取和建库流程对mRNA-Seq的影响 已有 10460 次阅读 2014-8-14 14:21 |个人分类:转录组测序|系统分类:科研笔记|关键词:转录组测序,RNA-Seq,,链特异性RNA ...
- 全渠道java b2b b2c o2o平台
大型企业分布式互联网电子商务平台,推出PC+微信+APP+云服务的云商平台系统,其中包括B2B.B2C.C2C.O2O.新零售.直播电商等子平台. 根据微服务化设计思想,结合spring cloud一 ...
- cpp 区块链模拟示例(四) 区块链工作量证明
本文主要在之前的区块链原形上添加了工作量证明,并且为后继的交易功能做好准备. 上一个章节我们已经创建了区块链的基本原形,但是区块的哈希计算和加入太过于简单,如果按照这种速度添加区块那么区块链估计一个小 ...