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 获取表单file全路径
Dec 31 Javascript
用js实现的模拟jquery的animate自定义动画(2.5K)
Jul 20 Javascript
jQuery表单域选择器用法分析
Feb 10 Javascript
详解JavaScript中的blink()方法的使用
Jun 08 Javascript
移除AngularJS下URL中的#字符的方法
Jun 19 Javascript
Vue.js中用v-bind绑定class的注意事项
Dec 13 Javascript
原生js实现节日时间倒计时功能
Jan 18 Javascript
react.js CMS 删除功能的实现方法
Apr 17 Javascript
详解webpack的proxyTable无效的解决方案
Jun 15 Javascript
小程序实现短信登录倒计时
Jul 12 Javascript
mock.js模拟数据实现前后端分离
Jul 24 Javascript
Vue3.0中的monorepo管理模式的实现
Oct 14 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
来自PHP.NET的入门教程
2006/10/09 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
2019/11/25 PHP
常用参考资料(手册)下载或者链接
2006/07/22 Javascript
js将json格式内容转换成对象的方法
2013/11/01 Javascript
写JQuery插件的基本知识
2013/11/25 Javascript
基于JavaScript实现瀑布流效果(循环渐近)
2016/01/27 Javascript
jQuery模拟Marquee实现无缝滚动效果完整实例
2016/09/29 Javascript
JS文件/图片从电脑里面拖拽到浏览器上传文件/图片
2017/03/08 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
2017/09/04 Javascript
Vue组件之极简的地址选择器的实现
2018/05/31 Javascript
js实现黑白div块画空心的图形
2018/12/13 Javascript
详解django模板与vue.js冲突问题
2019/07/07 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
2019/07/15 Javascript
vue轮播组件实现$children和$parent 附带好用的gif录制工具
2019/09/26 Javascript
浅析Vue 防抖与节流的使用
2019/11/14 Javascript
JavaScript数组类型Array相关的属性与方法详解
2020/09/08 Javascript
Python3写入文件常用方法实例分析
2015/05/22 Python
Python爬虫框架Scrapy实战之批量抓取招聘信息
2015/08/07 Python
python杀死一个线程的方法
2015/09/06 Python
Python中如何将一个类方法变为多个方法
2019/12/30 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
2020/03/10 Python
德国网上药房:Apotal
2017/04/04 全球购物
戴尔英国翻新电脑和电子产品:Dell UK Refurbished Computers
2019/07/30 全球购物
大学生职业规划范文:象牙塔生活的四年计划
2014/01/14 职场文书
建筑工程毕业生自我鉴定
2014/01/14 职场文书
晚会主持词开场白
2014/03/17 职场文书
水利专业大学生职业生涯规划书范文
2014/09/17 职场文书
债务授权委托书范本
2014/10/17 职场文书
党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
2015年学校体育工作总结
2015/04/22 职场文书
信息技术国培研修日志
2015/11/13 职场文书
2016年暑期见闻作文
2015/11/25 职场文书
事业单位工作人员岗前培训心得体会
2016/01/08 职场文书
大学生军训心得体会5篇
2019/08/15 职场文书
2022年四月新番
2022/03/15 日漫