JavaScript中的闭包

什么是闭包?

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行的
下面用一些代码来解释这个定义:

function foo() {var a = 2;function bar() {console.log(a);   // 2}bar();
}foo();

这是闭包吗?
技术上来讲,也许是。但根据前面的定义,确切地说并不是。最准确地来解释 bar() 对 a 的应用方法是词法作用域的查找规则(即在 bar() 的函数作用域中无法找到 a,则向上一级所嵌套的 foo() 的作用域中查找),而这些规则只是闭包的一部分。
下面再看一段代码,清晰地展示了闭包:

function foo() {var a =  2;function bar() {console.log(a);}return bar;
}var baz = foo();baz();   // 2   这就是闭包的效果

函数 bar() 的词法作用域能够访问 foo() 的内部作用域,然后将 bar() 函数本身作为一个值类型进行传递。在这段代码中,我们将 bar 所引用的函数对象本身作为返回值。在 foo() 执行后,其返回值赋值给变量 baz 并调用 baz(),实际上只是通过不同的标识符引用调用了内部函数 bar()
在 foo() 执行后,通常会期待 foo() 的整个内部作用域都被销毁。而闭包的神奇之处可以阻止作用域被销毁,被回收。那么是谁再使用这个内部作用域?是 bar() 本身在使用。bar() 拥有覆盖 foo() 内部作用域的闭包,使得该作用域能够一直存活,以供 bar() 在之后任何时间进行引用。这个引用就叫做闭包。
再据两个例子:

function foo() {var a = 2;function baz() {console.log(a);   //2}bar(baz);
}function bar(fn) {fn();   // 这就是闭包
}
function wait(message) {setTimeout(function timer(){console.log(message);},1000);
}wait("Hello World");

循环和闭包

先看下面的例子:

for(var i=1; i<=5; i++){setTimeout(function timer() {console.log(i);},i*1000);
}

这段代码在运行时会以每秒一次的频率输出五次6.为什么会这样呢?
首先解释6是怎么来的。这个循环的终止条件是 i<=5。条件首次成立时 i 的值是6.因此,输出显示的是循环结束时 i 的最终值。
延迟函数的回调会在循环结束时才执行,当定时器运行时即使每个迭代中执行的是 setTimeout(..,0),所有的回调函数依然是在勋魂结束后才会执行,因此每次都输出6.根据作用域的工作原理,实际情况是尽管循环中的五个函数是在各个迭代中分别定义的,但是它们都是被封闭在一个共享的全局作用域中,因此实际上只有一个 i
再看下一个代码,给上一代码加入更多的词法作用域,且要加入实质内容才能起作用。

for(var i=1; i<=5; i++){(function() {var j = i;setTimeout(function timer(){console.log(j);},j*1000)})();
}

现在就能正常分别输出数字1~5,每秒一次,每次一个。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/260685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第4章 Python 数字图像处理(DIP) - 频率域滤波12 - 选择性滤波 - 带阻

目录选择性滤波带阻滤波器和带通滤波器陷波滤波器选择性滤波 处理特定的频带的滤波器称为频带滤波器 带阻滤波器&#xff1a; 若某个频带中的频率被滤除 带通滤波器&#xff1a; 若某个频带中的频率被通过 处理小频率矩形区域的滤波器称为陷波滤波器 陷波带阻滤波器&#x…

command line

对chrome 的IPC 感兴趣&#xff0c;想通过他的单元测试来窥探。 无意中看到有一个command_line 类&#xff0c;因为是第二次碰到 &#xff2f;&#xff33;&#xff27;中也有一个&#xff43;&#xff4f;&#xff4d;&#xff4d;&#xff41;&#xff4e;&#xff44;类正好…

[物理学与PDEs]第1章第4节 电磁能量和电磁动量, 能量、动量守恒与转化定律 4.3 电磁能量 (动量) 密度, 电磁能量流 (动量流) 密度...

1. 电磁能量密度: $\cfrac{1}{2}\sex{\ve_0E^2\cfrac{1}{\mu_0}B^2}$. 2. 电磁能量流密度向量: ${\bf S}\cfrac{1}{\mu_0}{\bf E}\times {\bf B}$. 3. 电磁动量密度向量: $\cfrac{1}{c^2}{\bf S}$. 4. 电磁动量流密度张量: $\cfrac{1}{2}\sex{\ve_0E^2\cfrac{1}{\mu_0}B^2}{\bf…

python打包工具报错_python打包生成exe报错

如图所示 如果出现的是这个问题可以可以考虑以下方法 首先卸载原先下载的 Pyinstaller pip uninstall pyinstaller 再执行以下代码&#xff0c;去github上下载 pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip 注释&#xff1a;再次打包&#xff…

创建DLL、Lib以及使用DLL、Lib

1.要在生成DLL文件的同时生成Lib文件&#xff0c;函数声明时前面要加__declspec(dllexport)。 可在头文件中如下定义&#xff1a; #ifndef __MYDLL_H #define __MYDLL_H#ifdef MYDLL_EXPORTS #define MYDLL __declspec(dllexport) #else #define MYDLL __declspec(dllimport) #…

去除lcd图片的摩尔纹_宝妈时尚产后有妊娠纹怎么办?教你这三招,轻松修复肚皮!...

产后肚子上长妊娠纹&#xff0c;相信是很多妈妈的痛点。首先我们来介绍一下什么是妊娠纹。由于妊娠期荷尔蒙的影响&#xff0c;加之腹部膨隆使皮肤的弹力纤维与胶原纤维损伤或断裂&#xff0c;腹部皮肤变薄变细&#xff0c;出现一些宽窄不同、长短不一的粉红色或紫红色的波浪状…

anaconda 换清华镜像源 windows

方法1 Windows 下安装好Anaconda 应该会有如下这些应用&#xff0c;我们打开如下图anaconda Prompt(下面简称prompt)&#xff0c;(当然CMD也可以&#xff0c;只是我比较喜欢用prompt) 打开如下图 使用下面命令&#xff0c;即可以添加清华镜像 conda config --add channels …

php冒泡排序和快速排序笔记

<?php $arr array(12,1,5,88,35,0,18,100,50,21,28,7,9,9.5);//交换两值 function swap(&$m, &$n){$temp $m;$m $n;$n $temp;/* 如数组中有小数时&#xff0c;以下方法会省略小数点后面的数$m $m ^ $n;$n $m ^ $n;$m $m ^ $n;*/ }//冒泡排序 function bubbl…

提高表格可读性的一些技巧

表格的应用由于工作原因&#xff0c;经常接触到表格。我们发现&#xff0c;表格不但广泛的运用在各类数据收集和分析&#xff0c;同时通过表格这样一种二维矩阵来整理和陈列信息时&#xff08;即便最后的展示方式并非一个典型的表格样式&#xff09;&#xff0c;能够很好的表达…

分页第一页用0还是1_如何设计api分页

常规的分页方式API处理分页看似简单&#xff0c;实际上暗藏危机。最常见的分页方式&#xff0c;大概是下面这样的/users/?page1&limit5//服务端返回最理想的情况下&#xff0c;客户端请求第一页的5条数据&#xff0c;服务端如常返回&#xff0c;比如下图:拿Twitter的图用一…

数据挖掘肿瘤预测_科研套路不嫌多,数据挖掘发3分

解螺旋公众号陪伴你科研的第2003天如何复现一篇3分生信研究做科研需要先学习套路&#xff0c;才能超越套路。今天给大家介绍的套路文献是今年发表在《Oncology reports》(IF 3.041)上的一篇文章。文章的标题虽然看上去比较泛&#xff0c;但也让读者一眼就能知道主题了&#xff…

Jupyter notebook 导出PDF的3种方法

很多用Jupyter notebook的都想导出PDF&#xff0c;但是我们点击Download as PDF via LaTex. 然后呢&#xff1f; Ohzzzzzzzzz 出现下图的错误&#xff0c;看到这里感觉糟糕透啦。虽然可以根据提供的方法解决这个问题。下面我说说我的方法吧。 方法1 打开jupyter notebook&a…

mybatis中的#{value}和${value}的区别

2019独角兽企业重金招聘Python工程师标准>>> 1. #{value}将传入的数据都当成一个字符串&#xff0c;会对自动传入的数据加一个双引号。 2. ${value}将传入的数据直接显示生成在sql中。 3. #{value}方式能够很大程度防止sql注入。  4.${value}方式无法防止Sql注入。…

数据库备份失败问题

备份对于服务器“服务器名”失败。&#xff08;Microsoft.SqlServer.Smo&#xff09; 其他信息&#xff1a;System.Data.SqlClient.SqlError:无法打开备份设备c:\abc.bak。出现操作系统错误5(拒绝访问。)。(Microsoft.SqlServer.Smo&#xff09; 解决办法&#xff1a; Sql Serv…

重写setTimeout扩展参数

1 //判断函数行参长度来决定是否需要重写setTimeout&#xff0c;ie8以下为undefined2 if(window.setTimeout.length undefined){3 var __sto window.setTimeout;4 window.setTimeout function(callback,timeout,param){5 var args Array.prototype.slice.c…

针对access数据库的增删改查

1、执行查询操作&#xff1a;&#xff08;ExecuteReader方法&#xff09; string myConnectionString "Provider Microsoft.Jet.OLEDB.4.0;Data Source "Server.MapPath("~/") "App_Data/access.mdb"; //使用相对路径连接数据库 string mySel…

pandas 在jupyter notebook时候能用,但在vscode, pycharm不能用

先看错误。 AttributeError: partially initialized module ‘pandas’ has no attribute ‘Series’ (most likely due to a circular import) 分一下这种错误 ‘…’ has no attribute ‘…’ 库没有 ’…’ 这种问题&#xff0c;要么库没有装好&#xff0c;或者装的库的…

解决 IDEA 调用其他类的时候自动加上包路径和类名的情况_idea 快捷键汇总(转)...

1.IDEA常用快捷键Alt回车 导入包,自动修正CtrlN 查找类CtrlShiftN 查找文件CtrlAltL 格式化代码CtrlAltO 优化导入的类和包AltInsert 生成代码(如get,set方法,构造函数等)CtrlE或者AltShiftC 最近更改的代码CtrlR 替换文本CtrlF 查找文本CtrlShiftSpace 自动补全代码Ctrl空格 代…

8位可控加减法器_自主可控:QTouch在军工道系统上的应用

自主可控&#xff1a;QTouch在军工道系统上的应用一、系统介绍"道系统"操作系统是一款面向各领域的嵌入式实时操作系统&#xff0c;支持单核及多核CPU硬件配置&#xff0c;可替换相关领域的VxWorks 6.8/6.9操作系统二、产品特性 具备自主知识产权的嵌入式实时操作系统…

截获所有以太网帧数据并进行具体分析

/* capture_packet.c - 截获所有以太网帧数据并进行具体分析 *//* 常用函数的头文件 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include <signal.h>/* 与网络相关…