JavaScript使用闭包模仿块级作用域操作示例


Posted in Javascript onJanuary 21, 2019

本文实例讲述了JavaScript使用闭包模仿块级作用域操作。分享给大家供大家参考,具体如下:

在阅读这篇文章之前,建议先阅读JavaScript的作用域链以及JavaScript闭包。

正如闭包的定义一样:“闭包指的是有权访问另一个函数作用域中的变量的函数”, 闭包最大的意义就在于闭包可以对另一个函数作用域的变量进行访问,由此,闭包可以延伸出一系列的用法。

模仿块级作用域

JavaScript没有块级作用域的概念。这意味着在块语句中定义的变量,实际上是包含在函数中而非语句中创建的。从作用域链的角度来理解是,所有在函数内定义的变量(所有,也就是说块语句中定义的变量也包含在内)都会在这个函数执行时所创建的函数的活动对象中,因此从函数内的所有变量定义开始,就可以在函数内部随处访问它,闭包也可以通过作用域链访问它。
例子:

function outputNumbers(count){
  for(var i = 0; i < count; i++){
    console.log(i); // 0, 1, ... count - 1
  }
  console.log(i); // count
}

C++, JAVA等语言中,变量i只会在for循环的语句块(block)中有定义,循环一旦结束,变量i就会被销毁。可是在JavaScript中,变量i是定义在outputNumbers()的活动对象中,因此从函数内的所有变量定义开始,就可以在函数内部随处访问它,闭包也可以通过作用域链访问它。即使像下面这样重新声明同一个变量,也不会改变它的值。

function outputNumbers(count){
  for(var i = 0; i < count; i++){
    console.log(i); // 0, 1, ... count - 1
  }
  var i;     // redeclare i
  console.log(i); // count
}

JavaScript从来不管是否多次声明了同一个变量;遇到这种情况,JavaScript只会对后续的声明视而不见(不过会执行后续声明中的变量初始化),将其当成一个赋值语句。

函数包装器可以用来模仿块作用域并避免这个问题。

函数包装器就是创建并立即调用一个函数。

(function(){
  console.log("Hello World!");
})();

这段代码直接输出”Hello World”, 这就是一个函数包装器。

函数包装器的作用:

1. 立即执行函数中的代码,又不会再内存中留下对该函数的引用;

2. 函数内部的所有变量都会被立即销毁(除非将这些变量赋值给了包含作用域中的变量)。

当在函数内部使用函数包装器的时候,此时函数包装器就是一个闭包,有权访问外部环境中的所有变量。

function outputNumbers(count){
  (function(){
    //块级作用域
    for(var i = 0; i < count; i++){
      console.log(i); // 0, 1, ... count - 1
    }
  })();
  console.log(i); // error
}

在函数包装器中可以访问外部环境outputNumbers()的变量count,打印0, 1, … count - 1,但是在函数包装器执行完毕之后,再访问变量i就会抛出错误,因为i是在函数包装器中定义的,outputNumbers()函数无法访问。

无论在什么地方,如果只需要一些临时变量,就可以使用块级作用域!

使用函数包装器这种闭包可以减少闭包过多占用内存的问题。因为没有指向匿名函数的引用, 所以只要函数包装器执行完毕,就可以立即销毁其作用域链了。

函数包装器这种技术经常在全局作用域中被用在函数外部,从而限制想全局作用域中添加过多的变量和函数。一般来说,我们都应该尽量少向全局作用域中添加变量和函数。过多的全局变量和函数很容易导致命名冲突。通过创建块级作用域,每个开发人员既可以使用自己的变量,有不必担心搞乱全局作用域。例如:

(function(){
  var now = new Date();
  if (now.getMonth() == 0 && now.getDate() == 1) {
    console.log("Happy new year");
  }
})();

将这段代码放在全局作用域中,可以用来确定哪天是一月一日。其中变量now现在是匿名函数中的局部变量,避免了在全局变量中创建。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
Json和Jsonp理论实例代码详解
Nov 15 Javascript
Javascript学习笔记之数组的遍历和 length 属性
Nov 23 Javascript
JavaScript实现清空(重置)文件类型INPUT元素值的方法
Nov 17 Javascript
jQuery简单实现MD5加密的方法
Mar 03 Javascript
JS中把函数作为另一函数的参数传递方法(总结)
Jun 28 Javascript
vue的基本用法与常见指令
Aug 15 Javascript
vue中v-cloak解决刷新或者加载出现闪烁问题(显示变量)
Apr 20 Javascript
mpvue小程序仿qq左滑置顶删除组件
Aug 03 Javascript
一些可能会用到的Node.js面试题
Jun 15 Javascript
微信小程序点击列表跳转到对应详情页过程解析
Sep 26 Javascript
vue cli4.0项目引入typescript的方法
Jul 17 Javascript
详解JavaScript 中的批处理和缓存
Nov 19 Javascript
JavaScript闭包与作用域链实例分析
Jan 21 #Javascript
js中事件对象和事件委托的介绍
Jan 21 #Javascript
JavaScript作用域链实例详解
Jan 21 #Javascript
Jquery的Ajax技术使用方法
Jan 21 #jQuery
js变量声明var使用与不使用的区别详解
Jan 21 #Javascript
Vue中Axios从远程/后台读取数据
Jan 21 #Javascript
vue项目中实现的微信分享功能示例
Jan 21 #Javascript
You might like
yii框架中的Url生产问题小结
2012/01/16 PHP
PHP对象Object的概念 介绍
2012/06/14 PHP
关于PHP session 存储方式的详细介绍
2013/06/25 PHP
JS 实现Table相同行的单元格自动合并示例代码
2013/08/27 Javascript
JS获取当前日期和时间的简单实例
2013/11/19 Javascript
js实现页面跳转的五种方法推荐
2016/03/10 Javascript
JavaScript实现页面跳转的方式汇总
2016/05/16 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
2016/05/25 Javascript
Vue2.0结合webuploader实现文件分片上传功能
2018/03/09 Javascript
js获取form表单中name属性的值
2019/02/27 Javascript
Vue使用axios出现options请求方法
2019/05/30 Javascript
这应该是最详细的响应式系统讲解了
2019/07/22 Javascript
vue:el-input输入时限制输入的类型操作
2020/08/05 Javascript
JavaScript事件循环及宏任务微任务原理解析
2020/09/02 Javascript
[27:39]Ti4 循环赛第二日 LGD vs Fnatic
2014/07/11 DOTA
[01:51]2018年度CS GO最具人气外援-完美盛典
2018/12/16 DOTA
python通过文件头判断文件类型
2015/10/30 Python
Python实现将json文件中向量写入Excel的方法
2018/03/26 Python
Python通过Manager方式实现多个无关联进程共享数据的实现
2019/11/07 Python
给Django Admin添加验证码和多次登录尝试限制的实现
2020/07/26 Python
Python request post上传文件常见要点
2020/11/20 Python
python 实现性别识别
2020/11/21 Python
英国旅游额外服务市场领导者:Holiday Extras(机场停车场、酒店、接送等)
2017/10/07 全球购物
Ellos瑞典官网:北欧地区时尚、美容和住宅领域领先的电子商务网站
2019/11/21 全球购物
留学生如何写好自荐信
2013/12/27 职场文书
创业者迈进成功第一步:如何写创业计划书?
2014/03/22 职场文书
捐书活动总结
2014/05/04 职场文书
放飞梦想演讲稿
2014/05/05 职场文书
感恩节活动策划方案
2014/05/16 职场文书
“六查”、“三学”、“三干”查摆问题整改措施
2014/09/27 职场文书
群众路线剖析材料
2014/09/30 职场文书
餐厅收银员岗位职责
2015/04/07 职场文书
《最后一头战象》教学反思
2016/02/16 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
nginx结合openssl实现https的方法
2021/07/25 Servers
Python Pandas 删除列操作
2022/03/16 Python