一篇文章带你了解JavaScript 函数闭包

大家好,我是前端进阶者。

JavaScript变量属于 本地 或者 全局 范围,使用闭包可以让私有变量成为可能。

一、全局变量

一个函数可以访问所有定义在函数 内部 的变量。

1function myFunction() { 2 var a = 4; 3 return a * a; 4}

但是函数也可以访问定义在函数 之外 的变量。

1 2var a = 4; //全局变量 3function myFunction() { 4 return a * a; 5}

第一个例子中,a是一个局部变量.。局部变量只能在定义的函数内使用。

全局变量可以被页面(和窗口)中所有脚本使用(和更改),具有相同名称的全局变量和局部变量是不同的变量。修改一个,不修改其他。

没有关键字var创建的变量,总是全局的,即使是在函数中创建的。

二、变量的生命周期

全局变量只要应用程序(窗口/网页)存在,它就存在。

局部变量生命周期较短。它们在函数被调用时被创建,当函数完成时被删除。

三、为什么需要闭包?

假设要使用一个变量来计数某物,并且希望该计数器可用于所有函数。可以使用一个全局变量和一个增加计数器的函数。这个时候就需要闭包。

案例:一个计数器

1 2<!DOCTYPE html> 3<html lang="en"> 4<head> 5<meta charset="UTF-8"> 6<title>项目</title> 7</head> 8<body style="background-color: aqua;"> 9<p>使用全局变量计数</p> 10 11<button type="button" onclick="myFunction()">计数!</button> 12 13<p id="demo">0</p> 14 15<script> 16var counter = 0; 17 18function add() { 19return counter += 1; 20} 21 22function myFunction() { 23document.getElementById("demo").innerHTML = add(); 24 /* the counter is now equal to 3*/ 25 } 26</script> 27</body> 28</html> 29

注:

计数器只被add()函数改变。问题是,页上的任何脚本可以改变计数器,无需调用add(),如果在函数中声明计数器,没有调用的时候,没有人能改变它 add()。

1 2function add() { 3 var counter = 0; //局部变量 4 counter += 1; 5} 6 7add(); 8add(); 9add();

每次都要调用add()函数,计数器被设置为1。

四、JavaScript嵌套函数

所有函数都可以访问全局作用域。

事实上,在JavaScript中,所有函数都能访问它们外部的变量。JavaScript支持嵌套函数. 嵌套函数可以访问它们 上面(外部) 的作用域。

实例中, 内部函数 plus() 在父函数中可以访问 counter 变量。

1 2function add() { 3 var counter = 0; 4 function plus() {counter += 1;} 5 plus(); 6 return counter; 7}

完整代码:

1 2<!DOCTYPE html> 3<html> 4<title>项目</title> 5 6<body style="background-color: aqua;"> 7 8<h2> JavaScript嵌套函数</h2> 9 10<p id="output"></p> 11 12<script> 13function outer() { 14var counter = 0; 15 16function inner() { 17counter++; 18} 19inner(); 20return counter; 21} 22 23document.getElementById("output").innerHTML = `计数器是: ${outer()}`; 24</script> 25 26</body> 27</html>

如果能从外部调用plus()函数,这可能已经解决了计数器的困境,还需要找到一种方法来执行 counter = 0 只执行一次,需要闭包。

五、JavaScript 闭包

自调用函数

变量add被分配了自调用函数的返回值,自调用函数只运行一次. 它将counter设置为零(0),并返回函数表达式。

1var add = (function () { 2 var counter = 0; 3 return function () {return counter += 1;} 4})(); 5 6add(); 7add(); 8add(); 9 10// the counter is now 3

这样 add 变成了一个函数. "精彩的" 部分是它可以在父作用域中访问counter。

注:

这就是所谓的 JavaScript 闭包, 它使函数有“私有”变量成为可能。counter受匿名函数的作用域保护, 并且只能使用add函数修改。

六、总结

本文基于JavaScript基础。从函数的基本概念,(变量和全局 )。函数为什么需要闭包,使用闭包可以让私有变量成为可能。通过案例(计数器)的讲解, 以及对嵌套函数中闭包的应用能够更好的理解。

丰富的效果图的展示,能够帮助更好的去理解闭包这一概念。

希望能够帮助你更好的学习JavaScript 。

-------------------********************************** End **********-------------**-----********-**********************************

往期精彩文章推荐:

欢迎各位大佬点击链接加入群聊【helloworld开发者社区】:https://jq.qq.com/?_wv=1027&k=mBlk6nzX进群交流IT技术热点。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

一篇文章带你了解JavaScript作用域

在JavaScript中,对象和函数也是变量。在JavaScript中,作用域是你可以访问的变量、对象和函数的集合。JavaScript有函数作用域:这个作用域在函数内变化。一、本地JavaScript变量一个变量声明在JavaScript函数内部,成为函数的局部变量。局部变量有局部作用域:它们只能在函数中访问。JS://codeherecann

Javascript中的变量提升

定义JavaScript中奇怪的一点是你可以在变量和函数声明之前使用它们。就好像是变量声明和函数声明被提升了代码的顶部一样。sayHi()//Hithere!functionsayHi()console.log('Hithere!')name'JohnDoe'console.log(name)//JohnDoevarn