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创建Silverlight Plugin以及自定义nonSilverlight和lowSilverlight样式
Jun 28 Javascript
js比较和逻辑运算符的介绍
Mar 10 Javascript
javascript中的正则表达式使用指南
Mar 01 Javascript
javascript编程异常处理实例小结
Nov 30 Javascript
简单实现js进度条加载效果
Mar 25 Javascript
详解ES6中的代理模式——Proxy
Jan 08 Javascript
vue 中动态绑定class 和 style的方法代码详解
Jun 01 Javascript
vue-for循环嵌套操作示例
Jan 28 Javascript
基于javascript实现贪吃蛇经典小游戏
Apr 10 Javascript
vue实现随机验证码功能(完整代码)
Dec 10 Javascript
vue3.0+vue-router+element-plus初实践
Dec 02 Vue.js
JavaScript Html实现移动端红包雨功能页面
Jan 10 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
vBulletin HACK----显示话题大小和打开新窗口于论坛索引页
2006/10/09 PHP
php实现jQuery扩展函数
2009/10/30 PHP
for循环连续求和、九九乘法表代码
2012/02/20 PHP
Yii2 rbac权限控制操作步骤实例教程
2016/04/29 PHP
php使用escapeshellarg时中文被过滤的解决方法
2016/07/10 PHP
Yii2实现跨mysql数据库关联查询排序功能代码
2017/02/10 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
Git命令之分支详解
2021/03/02 PHP
指定位置如果有图片显示图片,无图片显示广告的JS
2010/06/05 Javascript
js 延迟加载 改变JS的位置加快网页加载速度
2012/12/11 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
jQuery针对各类元素操作基础教程
2014/08/29 Javascript
js弹出对话框方式小结
2015/11/17 Javascript
微信小程序 css使用技巧总结
2017/01/09 Javascript
关于页面刷新vuex数据消失问题解决方案
2017/07/03 Javascript
Vue2 模板template的四种写法总结
2018/02/23 Javascript
vue.js做一个简单的编辑菜谱功能
2018/05/08 Javascript
Vue Promise的axios请求封装详解
2018/08/13 Javascript
详解promise.then,process.nextTick, setTimeout 以及 setImmediate的执行顺序
2018/11/21 Javascript
Python下的Mysql模块MySQLdb安装详解
2014/04/09 Python
Python 的 Socket 编程
2015/03/24 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
Sanic框架配置操作分析
2018/07/17 Python
python字典的setdefault的巧妙用法
2019/08/07 Python
Tensorflow: 从checkpoint文件中读取tensor方式
2020/02/10 Python
python数据类型可变不可变知识点总结
2020/03/06 Python
表达自我的市场:Society6
2018/08/01 全球购物
EJB面试题
2015/07/28 面试题
策划总监岗位职责
2014/02/16 职场文书
硕士生找工作求职信
2014/07/05 职场文书
开展党的群众路线教育实践活动情况汇报
2014/11/05 职场文书
家属联谊会致辞
2015/07/31 职场文书
创业方案:赚钱的烧烤店该怎样做?
2019/07/05 职场文书
HTML通过表单实现酒店筛选功能
2021/05/18 HTML / CSS
纯html+css实现打字效果
2021/08/02 HTML / CSS
MySQL数据库实验实现简单数据库应用系统设计
2022/06/21 MySQL