JavaScript实战之闭包与函数调用的相互应用详解

简介: JavaScript实战之闭包与函数调用的相互应用详解

JavaScript闭包

在这里插入图片描述

JavaScript变量可以是局部变量或全局变量。
私有变量可以使用闭包。

全局变量

函数可以访问函数内部定义的变量,例如:

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

在这里插入图片描述
在后一个示例中,a是全局变量。
在网页中,全局变量属于窗口对象。
全局变量可以应用于页面上的所有脚本。
在第一个示例中,a是局部变量。
局部变量只能在定义它的函数内使用。不适用于其他函数或脚本代码。
全局变量和局部变量是两个不同的变量,即使它们具有相同的名称。修改其中一个不会影响另一个的值。

如果在声明变量时不使用VaR关键字,则它是全局变量,即使它是在函数中定义的。

变量生命周期

全局变量的范围是全局的,也就是说,在整个JavaScript程序中,全局变量无处不在。
函数内声明的变量仅在函数内工作。这些变量是局部变量,范围是局部的;函数的参数也是局部的,仅在函数内工作。

计数器困境

想象一下,如果您想对一些值进行计数,并且计数器在所有函数中都可用。
您可以使用全局变量设置计数器:

var counter = 0;
 
function add() {
   return counter += 1;
}
 
add();
add();
add();

运行结果如下:
在这里插入图片描述
执行add()函数时,计数器值会更改。
但问题是,即使没有调用add()函数,页面上的任何脚本都可以更改计数器。
如果在函数中声明计数器,则在不调用函数的情况下无法修改计数器的值:
在这里插入图片描述
本意是想输出 3, 但事与愿违,输出的都是 1

function add() {
    var counter = 0;
    return counter += 1;
}
 
add();
add();
add();

在这里插入图片描述
上述代码将无法正确输出。每次调用add()函数时,计数器将设置为1。
JavaScript嵌入函数可以解决这个问题。

JavaScript 内嵌函数

所有函数都可以访问全局变量。
事实上,在JavaScript中,所有函数都可以访问上一层的范围。
JavaScript支持嵌套函数。嵌套函数可以访问上一级的函数变量。
在本例中,嵌入式函数plus()可以访问父函数的计数器变量:

function add() {
    var counter = 0;
    function plus() {counter += 1;}
    plus();    
    return counter; 
}

如果我们可以从外部访问plus()函数,我们就可以解决计数器的困境。
我们还需要确保counter=0只执行一次。
我们需要关闭。

JavaScript 闭包

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
 
add();
add();
add();

变量add指定函数自调用的返回字值。
自调用函数只执行一次。将计数器设置为0。并返回函数表达式。
add变量可用作函数。最重要的是,它可以访问函数上方一级作用域中的计数器。
这称为JavaScript闭包。它使得函数可以具有私有变量。
计数器受匿名函数的作用域保护,只能通过add方法修改。

作为一个函数调用

myFunction(10, 2) 返回 20

function myFunction(a, b) {
    return a * b;
}
myFunction(10, 2); 

上述函数不属于任何对象。但它始终是JavaScript中的默认全局对象。
html中的默认全局对象是html页面本身,因此函数属于html页面。
浏览器中的页面对象是浏览器窗口(窗口对象)。上述函数将自动成为窗口对象的函数。
Myfunction()和window Myfunction()

function myFunction(a, b) {
    return a * b;
}
window.myFunction(10, 2);

当函数没有被它自己的对象调用时,该函数的值将成为全局对象。
在web浏览器中,全局对象是浏览器窗口(窗口对象)。
此实例返回的值为窗口对象:

function myFunction() {
    return this;
}
myFunction(); 
当函数作为全局对象调用时,其值将成为全局对象。
使用窗口对象作为变量很容易导致程序崩溃。

作为函数方法调用函数

在JavaScript中,函数是对象。JavaScript函数有其属性和方法。
Call()和apply()是预定义的函数方法。可以使用两种方法调用函数。两个方法的第一个参数必须是对象本身。

function myFunction(a, b) {
    return a * b;
}
myObject = myFunction.call(myObject, 10, 2);  

两种方法都使用对象本身作为第一个参数。两者之间的区别是第二个参数:apply在参数数组中传递,也就是说,多个参数组合成一个数组,call作为call的参数传入(从第二个开始)。

function myFunction(a, b) {
    return a * b;
}
myArray = [10, 2];
myObject = myFunction.apply(myObject, myArray);

在JavaScript严格模式下,调用函数时,第一个参数将成为this的值,即使该参数不是对象。
在JavaScript非严格模式下,如果第一个参数的值为null或未定义,它将使用全局对象。

相关文章
|
3天前
|
开发框架 JavaScript 中间件
中间件应用Koa.js(Node.js)
我们添加了两个中间件。第一个中间件记录请求的开始时间,并在下一个中间件执行完毕后计算并打印出请求的总时间。第二个中间件与之前的示例相同,它设置响应体为 "Hello World"
19 6
|
3天前
|
JavaScript 中间件 API
中间件应用Express.js(Node.js)
我们定义了一个名为 `logger` 的中间件函数。它接受请求对象、响应对象以及下一个中间件函数作为参数。当接收到请求时,它会打印出请求的 HTTP 方法和 URL,然后调用 `next()` 函数来将控制权传递给下一个中间件或路由处理器。我们使用 `app.use()` 方法将 `logger` 中间件添加到了应用级别的中间件堆栈中,这意味着它将对所有请求生效。
12 3
|
4天前
|
前端开发 JavaScript
闭包在JavaScript中有许多应用场景
闭包在JavaScript中发挥关键作用,如封装私有变量和函数提升安全性,维护变量生命周期,实现高阶函数,模拟块级作用域,支持回调函数以处理异步操作,以及促进模块化编程,增强代码组织和管理。闭包是理解和掌握JavaScript高级特性的重要一环。
21 7
|
5天前
|
数据采集 JavaScript 数据可视化
Node.js爬虫在租房信息监测与分析中的应用
Node.js爬虫在租房信息监测与分析中的应用
|
11天前
|
开发框架 JavaScript 前端开发
【JavaScript 与 TypeScript 技术专栏】TypeScript 在 Web 开发中的前沿应用
【4月更文挑战第30天】TypeScript在Web开发中日益重要,以其强大的类型系统提升代码质量,支持组件化开发,与React、Vue、Angular等框架良好集成。在大型项目管理中,TypeScript助于代码组织和优化,提高团队协作效率。此外,它提升开发体验,提供智能提示和错误检测。众多成功案例证明其前沿应用,未来将在Web开发领域持续发挥关键作用。
|
11天前
|
前端开发 JavaScript 网络协议
【JavaScript技术专栏】WebSockets在JavaScript中的应用
【4月更文挑战第30天】WebSocket是为解决HTTP协议在实时通信上的局限而诞生的技术,提供全双工、持久连接的通信方式,适合在线聊天、实时游戏等场景。JavaScript中的WebSocket API使浏览器与服务器能建立持久连接,通过事件处理连接、发送/接收数据及错误。相较于AJAX轮询和长轮询,WebSockets更高效、实时,是现代Web实时通信的优选。
|
11天前
|
JavaScript 前端开发 开发工具
【JavaScript 技术专栏】Node.js 基础与实战
【4月更文挑战第30天】本文介绍了Node.js的基础及应用,包括事件驱动的非阻塞I/O、单线程模型和模块系统。内容涵盖Node.js的安装配置、核心模块(如http、fs、path)及实战应用,如Web服务器、文件操作和实时通信。文章还讨论了Node.js的优劣势、与其他技术的结合,并通过案例分析展示项目实施流程。总结来说,Node.js是高效后端开发工具,适合构建高并发应用,其广阔的应用前景值得开发者探索。
|
11天前
|
移动开发 JavaScript 前端开发
【JavaScript技术专栏】Web Worker在JavaScript中的应用
【4月更文挑战第30天】HTML5的Web Worker API解决了JavaScript单线程性能瓶颈问题,允许在后台线程运行JS代码。本文介绍了Web Worker的基本概念、类型、用法和应用场景,如复杂计算、图像处理和数据同步。通过实例展示了搜索建议、游戏开发和实时数据分析等应用,并提醒注意其无法直接访问DOM、需消息传递通信以及移动端资源管理。Web Worker为前端开发提供了多线程能力,提升了Web应用性能和用户体验。
|
2月前
|
设计模式 JavaScript 前端开发
js开发:请解释闭包(closure)是什么,以及它的用途。
闭包是JavaScript中的关键特性,允许函数访问并操作外部作用域的变量,常用于实现私有变量、模块化和高阶函数。私有变量示例展示了如何创建无法外部访问的计数器;模块化示例演示了封装私有变量和函数,防止全局污染;高阶函数示例则说明了如何使用闭包创建能接收或返回函数的函数。
18 2
|
5月前
|
自然语言处理 JavaScript 前端开发
JavaScript基础知识:什么是闭包(Closure)?
JavaScript基础知识:什么是闭包(Closure)?
27 0