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 相关文章推荐
javascript 学习之旅 (3)
Feb 05 Javascript
JavaScript 编写匿名函数的几种方法
Feb 21 Javascript
javascript onmouseout 解决办法
Jul 17 Javascript
addEventListener和attachEvent二者绑定的执行函数中的this不相同
Dec 09 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
Sep 27 Javascript
ie7+背景透明文字不透明超级简单的实现方法
Jan 17 Javascript
修改或扩展jQuery原生方法的代码实例
Jan 13 Javascript
Vue.js 父子组件通讯开发实例
Sep 06 Javascript
原生js实现新闻列表展开/收起全文功能
Jan 20 Javascript
uploader秒传图片到服务器完整代码
Apr 22 Javascript
详解动画插件wow.js的使用方法
Sep 13 Javascript
Jquery Fade用法详解
Nov 06 jQuery
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
Email+URL的判断和自动转换函数
2006/10/09 PHP
在PHP中设置、使用、删除Cookie的解决方法
2013/05/06 PHP
php使用pdo连接报错Connection failed SQLSTATE的解决方法
2014/12/15 PHP
php实现用于验证所有类型的信用卡类
2015/03/24 PHP
PHP面向对象学习之parent::关键字
2017/01/18 PHP
CSS JavaScript 实现菜单功能 改进版
2008/12/09 Javascript
基于jquery的inputlimiter 实现字数限制功能
2010/05/30 Javascript
Jquery css函数用法(判断标签是否拥有某属性)
2011/05/28 Javascript
Jquery 点击按钮显示和隐藏层的代码
2011/07/25 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
2012/04/12 Javascript
利用div+jquery自定义滚动条样式的2种方法
2013/07/18 Javascript
JavaScript多并发问题如何处理
2015/10/28 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
2016/05/25 Javascript
AngularJS 依赖注入详解和简单实例
2016/07/28 Javascript
AngularJS中如何使用echart插件示例详解
2016/10/26 Javascript
如何防止INPUT按回车自动提交表单FORM
2016/12/06 Javascript
js 中rewrap-ajax.js插件实例代码
2017/10/20 Javascript
详解Vue前端对axios的封装和使用
2019/04/01 Javascript
webpack项目使用eslint建立代码规范实现
2019/05/16 Javascript
ElementUI radio组件选中小改造
2019/08/12 Javascript
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
javascript中layim之查找好友查找群组
2021/02/06 Javascript
Python笔记(叁)继续学习
2012/10/24 Python
Python matplotlib绘制图形实例(包括点,曲线,注释和箭头)
2020/04/17 Python
关于Python错误重试方法总结
2021/01/03 Python
亚马逊印度站:Amazon.in
2017/10/15 全球购物
联想加拿大官方网站:Lenovo Canada
2018/04/05 全球购物
向全球直邮输送天然健康产品:iHerb.com
2020/05/03 全球购物
Solaris操作系统的线程机制
2015/07/28 面试题
工业自动化专业毕业生推荐信
2013/11/18 职场文书
大学生村官心得体会范文
2014/01/04 职场文书
大学校园生活自我鉴定
2014/01/13 职场文书
30年同学聚会感言
2014/01/30 职场文书
家长对老师的评语
2014/04/18 职场文书
重大事项社会稳定风险评估方案
2014/06/15 职场文书
同步小康驻村工作简报
2015/07/20 职场文书