前端(十三)——JavaScript 闭包的奥秘与高级用法探索

😶博主:小猫娃来啦
😶文章核心:深入理解 JavaScript 中的闭包
文章目录
- 不理解闭包?这玩意很难?
- 闭包的定义与原理
- 闭包是什么
- 创建一个闭包
- 闭包的应用场景
- 闭包与作用域
- 闭包与作用域之间的关系
- 全局作用域、函数作用域和闭包的区别
- 闭包对变量生命周期的影响
- 闭包的优点和挑战
- 闭包带来的优点
- 闭包可能带来的挑战
- 使用闭包的注意事项
- 闭包使用案例和实际场景
- 学习资源推荐
不理解闭包?这玩意很难?
⭐⭐⭐关键点1
想象一下你在家里做饭,准备了一些食材和炉灶。闭包就像是你在炉灶旁边放了一个小盒子,里面有你需要用到的调料和工具。
这个小盒子就是一个闭包,里面装着你做饭时所需的东西。当你开火炒菜时,你可以随意使用盒子里的调料和工具,而不需要每次去厨房找。
闭包的作用就是让你方便地使用盒子里的东西,而不需要每次都去找它们。它把函数和相关的数据打包在一起,形成一个容器,你可以随时拿来使用。
这样的话,闭包就是帮助你更方便地存储和访问函数需要的数据,就像是一个移动的小工具箱,可以随时拿来用,而不需要每次都重新准备。
闭包的两个特点:
⭐⭐⭐关键点2
- 闭包内的函数可以访问外部函数中定义的变量。就像是一个保险柜,只有它自己知道密码,可以打开柜门取出里面的东西。
- 闭包函数可以保存在其他地方并被调用,但它仍然可以访问它创建时的环境。就像是一个存钱罐,你可以把它放在任何地方,以后需要时还可以取出里面的钱。
闭包有什么用呢?
- 封装:闭包可以帮助我们创建私有变量和函数,避免命名冲突,保护数据安全。
- 数据保持:闭包可以让函数内部的变量在函数执行结束后依然存在,方便后续使用。
- 回调和异步操作:闭包常用于创建回调函数,处理异步操作时能够保存一些状态信息并进行访问和更新。
- 模块化开发:闭包可以帮助我们创建模块化的代码,把相关功能和数据封装在闭包中,提供更高层次的抽象和封装。
如果你是对闭包有深入理解的。你肯定知道,在使用时要慎重,不能滥用闭包,否则可能会导致内存泄漏和性能消耗问题。
那么为什么会导致内存泄漏并且消耗性能呢?
⭐⭐⭐关键点3
假设你经常旅行,每次都会随身带着一个行李箱。如果你一直把不用的物品留在行李箱里,时间久了,行李箱就会变得很重,而且占用了不必要的空间。
闭包也是一样的道理。如果你滥用闭包,将不再需要的变量存储在闭包中,并且没有及时释放它们,就会导致内存泄漏和性能问题。
内存泄漏就好像行李箱里的物品积压太多,无法清理干净,最终导致浪费资源。如果我们不断创建和使用闭包,但又没有及时释放不再需要的部分,那么这些变量将一直占据着内存,造成内存的浪费。
性能问题则类似于携带过重的行李箱,给你的旅程增加了负担。如果闭包中存储了大量的变量和函数,每次使用它们时都要在内存中查找,这将耗费更多的时间和计算资源。对于大型项目或频繁调用的代码,这可能会显著影响程序的性能。
因此,在使用闭包时,我们需要慎重对待。及时释放不再需要的资源,避免滥用闭包,以免引起内存泄漏和性能问题。就像旅行时要定期整理行李箱一样,我们也要确保及时清理不再需要的闭包,让代码更加高效和可靠。
如果你不理解闭包,那么现在你应该对闭包有些认识了。总而言之,闭包是个超级大盒子。你如果是理发师,那这个大盒子里就装着各种发蜡,剪刀,洗发水,刮胡刀,剃头刀,染发剂,烫头的药水,吹风机等等。你要用什么就拿什么,这样子就会看起来非常规整,不需要满房间去找我需要的工具。但也有坏处,虽然看起来这个事归规规矩。但是如果东西太多,把某些物品压在箱底了,你想用的话,得从最上面的物品一直往下翻,会很累。如何避免呢?那就是尽可能的少放东西,一个工具用完放在固定位置,不要乱扔,避免下次用的时候难找。
所谓闭包,就是这么一个东西。
好的闭包:
糟糕的闭包:

假如你是程序,你说第一张图和第二张图,哪个图里找东西费事?你喜欢哪个闭包?
所以,闭包不仅是一种技术,更是一种思维方式,它可以帮助我们编写更优雅和高效的代码,也可以让我们的生活各个方面井井有条。
闭包的定义与原理
闭包是什么
闭包是一种特殊的函数对象,它包含了函数的代码和在创建该函数时所处环境中的变量。简单来说,闭包就是一个函数和与之相关的引用的组合体。
当一个函数内部定义了另一个函数,并且内部函数可以访问外部函数的变量时,我们就可以称这个内部函数为闭包。闭包可以“记住”创建它时的环境,即使在其定义的上下文已经不存在时仍然可以访问那些变量。
这就像是一个函数带着一个包裹,包裹里面装着函数所需的数据。当我们调用这个闭包时,它会携带着这个包裹,使得内部函数能够继续访问和操作包裹里的数据。
闭包有几个重要的特点:
- 可以捕获并访问定义它的外部函数的变量。
- 可以在函数外部被调用,以便在不同的上下文中使用。
- 可以被当作参数传递给其他函数,或者作为函数的返回值。
总结起来,闭包就是一个函数和它周围的状态(即定义它时所处的环境)的组合。它能够记住创建时的上下文,并允许我们在以后的任何时间访问和操作这些数据。
创建一个闭包
var a = 5;var outerFunction = function() {var b = 3;function innerFunction() {return a + b;}return innerFunction;
};var result = outerFunction();
console.log(result()); // 输出:8
我们分析一下这段代码:
首先,在全局作用域中定义了变量 a,赋值为 5。
然后,定义一个匿名函数,并将其赋值给 outerFunction 变量。在匿名函数内部,定义了变量 b,赋值为 3。然后在匿名函数内部定义了 innerFunction 函数,它引用了外部函数的变量 a 和内部函数的变量 b。最后,返回内部函数 innerFunction,形成了闭包。
紧接着,调用外部函数 outerFunction 并将返回的结果赋值给 result 变量。这里实际上是获取了一个闭包,该闭包包含了 innerFunction 和它引用的外部变量 a 和 b。
最后,调用闭包中的 innerFunction 函数,它会返回 a + b 的值。在这里,a 的值是外部变量的值 5,而 b 的值是外部函数中的变量 3。因此,result() 的结果为 8。
通过在函数内部定义另一个函数并引用外部函数的变量,这就成功地创建了一个闭包。闭包可以访问和操作外部函数的变量,即使外部函数已经执行完毕。这样我们可以在之后的任何时间调用闭包,并且它会使用当初创建时的上下文信息。
基于上面的例子,我们分析一下闭包的原理和工作机制
闭包是一种特殊的函数对象,它包含了函数本身以及它被创建时所处的环境(外部函数的变量)。这使得闭包可以在函数执行完毕后仍然访问和操作其外部函数的变量。
闭包的工作机制可以总结为以下几个步骤:
-
函数定义:当一个函数内部定义了另一个函数时,内部函数就可以引用外部函数的变量。
-
变量捕获:当内部函数引用外部函数的变量时,JavaScript 引擎会在内部函数的执行环境中创建一个变量的引用。这个引用捕获了外部函数的变量,并保存在闭包中。
-
外部函数执行结束:在外部函数执行完成后,根据 JavaScript 的垃圾回收机制,其局部变量通常会被销毁。但是,由于内部函数仍然引用了这些变量,它们不会被回收,而是被包含在闭包中。
-
闭包形成:当外部函数返回内部函数时,实际上返回的是该内部函数以及它所引用的外部变量的闭包。闭包包含了函数本身以及它被创建时的环境信息。
-
闭包的使用:返回的闭包可以在之后的任何时间内被调用,它能够访问和操作外部函数的变量,即使外部函数已经执行完毕。这是因为闭包中保存了被捕获的变量的引用。
闭包的原理基于 JavaScript 的词法作用域规则和垃圾回收机制。通过利用闭包,我们可以实现一些高级的编程技巧,例如模块模式、私有变量和函数的记忆化等。同时也需要注意,由于闭包可以保留对外部变量的引用,所以在使用闭包时要小心内存管理,避免造成内存泄漏。
闭包的应用场景
模块化开发: 闭包在模块化开发中起到了封装和隐藏变量的作用,使得我们可以创建独立的模块,并且只暴露需要外部访问的接口。这种方式可以提高代码可维护性和重用性。
var counter = (function() {var count = 0;return {increment: function() {count++;},decrement: function() {count--;},getCount: function() {return count;}};
})();counter.increment();
console.log(counter.getCount()); // 输出: 1
在上面的例子中,我们使用闭包创建了一个计数器模块。count 是一个私有变量,只有通过返回的对象才能访问它。这样可以防止外部直接修改计数值,同时提供了三个方法 increment、decrement 和 getCount 来操作计数器。
事件处理: 闭包经常用于事件处理函数,它可以捕获事件发生时的上下文信息,并在之后的某个时间点执行这个函数。这使得事件处理函数可以访问当前作用域以及外部作用域中的变量。
function createButton() {var count = 0;var button = document.createElement('button');button.innerText = 'Click me';button.addEventListener('click', function() {count++;console.log('Button clicked ' + count + ' times');});return button;
}var myButton = createButton();
document.body.appendChild(myButton);
我们创建了一个按钮,并给它添加了点击事件处理函数。事件处理函数可以访问并更新外部函数 createButton 中的变量 count,每次点击按钮时计数器就会增加。
异步编程: 闭包在异步编程中也有广泛的应用。由于 JavaScript 是单线程的,异步操作常常涉及到回调函数。而闭包可以捕获回调函数所需的上下文信息,使得在回调函数被调用时能够访问正确的变量。
function fetchData(url, callback) {// 发起异步请求fetch(url).then(function(response) {// 根据响应处理数据return response.json();}).then(function(data) {// 调用回调函数并传入数据callback(data);});
}function displayData(data) {console.log(data);
}fetchData('接口链接', displayData); // 异步获取数据并在回调函数中显示
这个例子中,fetchData 函数使用闭包实现了异步数据的获取。在最后一步调用 fetchData 时,我们传入一个回调函数 displayData,当数据请求成功后会被调用并传入获取到的数据。
闭包与作用域
闭包与作用域之间的关系
闭包与作用域之间有着密切的关系。在理解闭包的概念时,有必要先理解作用域的概念。
作用域定义了变量和函数的可访问范围。在JavaScript中,作用域通常是通过函数来创建的。每当你声明一个函数时,都会创建一个新的作用域。
闭包是指函数能够访问其词法作用域以外的变量的能力。具体来说,当一个函数内部引用了外部作用域的变量时,即使外部函数已经执行完毕,这个函数仍然可以使用该变量。
闭包实际上是一个函数和其相关的词法环境的组合。词法环境包含了在函数定义时所存在的所有局部变量、参数和其它函数。
闭包的出现是由于JavaScript采用的是词法作用域,它在函数定义的时候就决定了变量的作用域。而不同的函数可以访问不同的作用域,从而形成了闭包。
下面的例子可以更好地说明闭包与作用域之间的关系:
function outer() {var x = 10;function inner() {console.log(x); // 内部函数引用了外部函数的变量x}return inner;
}var closure = outer(); // 外部函数执行,并将内部函数返回
closure(); // 输出: 10
在这个例子中,inner 函数引用了外部函数 outer 中的变量 x。即使 outer 函数执行完毕并返回了 inner 函数,inner 函数依然可以访问和使用 x 变量。这是因为 inner 函数形成了一个闭包,包含了对 outer 函数作用域的引用。
可以总结如下:
- 作用域决定了哪些变量可以被访问和使用。
- 闭包可以让函数继续访问外部作用域中的变量,即使外部函数已经执行完毕。
- 闭包是由函数和其相关的词法环境组成,它允许函数访问外部作用域中的变量。
理解闭包与作用域之间的关系对于在JavaScript中正确使用闭包非常重要。它可以帮助我们更好地封装变量、实现模块化开发并处理异步操作等。
全局作用域、函数作用域和闭包的区别
全局作用域、函数作用域和闭包是 JavaScript 中不同的概念,它们在作用域范围和变量访问方面有所不同。
- 全局作用域:
- 全局作用域是在整个代码中都可访问的作用域。
- 在浏览器中,全局作用域一般是指在
<script>标签或外部 JavaScript 文件中定义的变量和函数。 - 全局作用域中声明的变量可以被后续的代码任意访问和修改。
- 函数作用域:
- 函数作用域是指在函数内部声明的变量只能在函数内部使用,外部无法访问。
- 函数作用域中的变量称为局部变量,它们只在函数内部有效。
- 每当函数被调用时,都会创建一个新的函数作用域,函数执行完毕后,其内部的变量会被销毁。
- 闭包:
- 闭包是指函数能够访问其定义时所在的词法作用域,即使函数在当前作用域外被调用。
- 闭包通过将函数及其相关的引用变量一起封装,形成一个独立的包裹,使得函数能够继续访问外部作用域中的变量。
- 闭包常用来实现函数的状态保留和数据私有化,以及模块化编程等功能。
- 闭包可以延长变量的生命周期,使得函数在不同的上下文中共享数据。
区别:
- 全局作用域是在整个代码中都可访问的作用域,函数作用域仅在函数内部有效,而闭包是函数能够访问其定义时所在的词法作用域。
- 全局作用域中的变量可以被后续的代码任意访问和修改,而函数作用域中的变量只在函数内部有效,外部无法访问。闭包可以让函数继续访问外部作用域中的变量,即使外部函数已经执行完毕。
- 全局作用域具有全局性,容易引起变量冲突和全局污染的问题;函数作用域和闭包提供了更好的封装性和隔离性,可以减少命名冲突和对全局命名空间的依赖。
总结: 全局作用域是最外层的作用域,在整个代码中都可访问;函数作用域是函数内部的作用域,只在函数内部有效;闭包是函数能够访问其定义时所在的词法作用域,即使函数在当前作用域外被调用。它们在作用域范围和变量访问方面有所不同,适用于不同的编程场景和需求。
闭包对变量生命周期的影响
闭包对变量生命周期的影响是延长了变量的生命周期。在普通的函数中,函数执行完毕后,函数作用域内的变量会被销毁,无法再被访问。但是当函数形成闭包时,闭包会持有函数内部的变量及其引用,使得这些变量在函数执行完毕后仍然可以被访问和操作。
具体来说,闭包通过保留其所在词法作用域的引用,使得这个作用域中的变量不会被垃圾回收机制回收,从而延长了变量的生命周期。这意味着在闭包外部的代码仍然可以访问和修改闭包中引用的变量。
闭包对变量生命周期的影响可以有以下几个方面:
- 变量在函数执行完毕后仍然可访问:闭包使得函数内部的变量不会随着函数的执行完毕而被销毁,从而使得外部代码仍然可以访问和操作这些变量。这为实现某些功能(如状态保留、数据私有化等)提供了可能性。
- 变量的值在闭包中得到保留:闭包中引用的变量的值会被保留下来,即使该变量原本位于函数作用域中。这可以让函数在不同的上下文中共享数据,实现了一种记忆效应。
- 变量可能无法被垃圾回收:由于闭包持有对变量的引用,导致这些变量无法被垃圾回收机制回收。如果闭包长时间存在,而其中引用的变量又占用较大的内存空间,可能会造成内存泄漏的问题。因此,在使用闭包时需要注意及时释放不再需要的闭包。
需要注意的是,虽然闭包可以延长变量的生命周期,但过度使用闭包或者使用不当可能会导致内存泄漏和性能问题。因此,在使用闭包时需要谨慎考虑其对变量生命周期的影响,确保合理管理和释放闭包中的资源。
闭包的优点和挑战
闭包带来的优点
闭包在 JavaScript 中带来了一些重要的优点,包括封装性和数据私有性。下面是对这些优点的详细探讨:
- 封装性(Encapsulation): 闭包可以实现函数和数据的封装,将它们组合在一起形成一个独立的单元。通过这种封装性,闭包可以隐藏内部的实现细节,只暴露必要的接口给外部使用。这种封装性使得代码更加模块化、可维护性更高,并且减少了全局命名空间的冲突。
- 数据私有性(Data Privacy): 闭包可以创建私有变量和私有函数,即只能在闭包内部访问和修改的变量和函数。这种数据私有性可以防止外部代码直接访问和篡改闭包中的数据,只能通过闭包提供的公共接口来间接操作。这样可以保护数据的完整性和安全性,避免不必要的外部干扰。
- 高级功能的实现: 闭包可以帮助实现一些高级功能,例如函数柯里化(Currying)、函数记忆(Function Memoization)和模块化等。通过利用闭包的特性,可以方便地定义和使用这些功能,提高代码的灵活性和可重用性。
- 保持状态(State Retention): 闭包可以保持函数的状态,即使函数执行完毕后依然保留该状态。这种能力使得函数在不同的调用之间共享数据和状态,可以实现一些需要保持状态的操作,如计数器、缓存等。
- 高效的事件处理: 闭包非常适合用于事件处理,特别是在多个事件处理程序中共享数据的场景下。通过将共享的数据保存在闭包中,每个事件处理程序都可以访问和修改这些数据,从而实现更灵活和高效的事件处理逻辑。
闭包可能带来的挑战
闭包在 JavaScript 中的使用可能会带来一些挑战,包括内存泄漏和性能问题。下面是对这些挑战的讨论:
- 内存泄漏: 闭包中的函数引用了外部函数的变量,这意味着外部函数中的变量不会被垃圾回收机制回收,即使它们已经不再需要。如果闭包长时间存在,并且其中引用的变量占用较大内存空间,就会导致内存泄漏的问题。为避免内存泄漏,我们应当谨慎管理闭包的生命周期,确保在不再需要时及时释放闭包。
- 性能问题: 由于闭包会持有对外部变量的引用,每次访问外部变量都需要在作用域链中查找,这可能导致性能下降。尤其是在循环中创建闭包时,闭包的创建和销毁过程可能会变得非常频繁,对性能产生负面影响。在性能敏感的场景中,应当谨慎使用闭包,尽可能减少闭包的创建和引用的变量数量,以提高代码执行效率。
- 内存消耗: 闭包会持有对外部变量的引用,导致这些变量无法被垃圾回收。如果闭包中引用的变量占用大量内存空间,就会增加整体的内存消耗。在处理大量数据或长时间运行的场景中,应当注意合理管理闭包,避免过度消耗内存。
- 难以追踪和调试: 使用闭包时,由于闭包内部可以访问外部作用域的变量,可能会增加代码的复杂性,使得调试变得更加困难。尤其是在多层嵌套的闭包中,追踪变量的来源和调试错误可能会变得更加复杂。
为了应对这些挑战,我们应当谨慎使用闭包,并且遵循一些最佳实践,如限制闭包的作用域范围、避免循环中创建闭包、及时释放不再需要的闭包等。此外,在开发过程中使用性能工具和内存分析工具来检测和解决潜在的问题也是很重要的。
使用闭包的注意事项
使用闭包时,以下是一些注意事项,可以帮助我们避免潜在的问题:
- 避免循环中创建闭包: 在循环中创建闭包可能导致性能问题,因为闭包的创建和销毁过程会频繁发生。可以通过使用立即执行函数表达式或函数绑定来解决这个问题,确保在循环中不会创建新的闭包。
- 尽量减少闭包引用的外部变量数量: 闭包会持有对外部变量的引用,因此闭包引用的变量越多,内存消耗也越大。在创建闭包时,尽量避免引用过多的外部变量,只引用必要的变量,以减少内存消耗。
- 关注闭包的生命周期: 确保及时释放不再需要的闭包,避免造成内存泄漏。在不再需要闭包时,将其引用置为 null,使得垃圾回收机制可以回收相关的内存空间。
- 使用模块模式: 模块模式是一种常见的使用闭包的方式,可以实现封装性和数据私有性。通过使用模块模式,可以明确指定哪些数据和函数对外可见,提高代码的可维护性。
- 谨慎使用全局变量: 当闭包中引用了全局变量时,可能会导致全局命名空间的冲突和内存泄漏。因此,在闭包中尽量避免引用过多的全局变量,尽量将需要共享的数据和函数封装在模块中。
- 追踪和调试: 由于闭包会增加代码的复杂性,追踪变量的来源和调试错误可能会变得更加困难。使用浏览器的开发者工具和调试器来帮助追踪和调试闭包相关的问题。
- 在性能敏感的场景中审慎使用闭包: 在对性能要求较高的场景中,要谨慎使用闭包,尽量减少闭包的创建和引用的变量数量,以提高代码的执行效率。
通过遵循这些最佳实践和注意事项,我们可以更好地使用闭包,减少潜在问题的出现,并提升代码的可读性、可维护性和性能。
闭包使用案例和实际场景
闭包在 JavaScript 中的使用非常灵活,可以应用于各种有趣的场景。以下是一些有趣的闭包使用案例和实际场景:
- 私有变量和封装: 闭包可以创建私有变量,通过将变量保存在闭包的作用域中,实现数据的封装和隐藏。这种模式可用于创建模块、插件或库,确保外部代码无法直接访问内部变量。
- 计数器和唯一标识符生成器: 闭包可以用于创建计数器函数,每次调用函数时自增计数。这在需要跟踪某个操作次数或生成唯一标识符时非常有用。
- 缓存机制: 闭包可以用于创建缓存函数,将函数的计算结果缓存起来,避免重复计算。这对于计算密集型操作或需要频繁调用且结果稳定的函数来说,能够提高性能。
- 事件处理器: 闭包经常用于创建事件处理器,在事件触发时执行特定的逻辑。闭包可以捕获事件处理器中所需的变量,并保持其状态。
- 循环中的异步操作: 在循环中使用闭包可以解决异步操作中的问题。典型的例子是在循环中使用闭包来处理异步请求,并确保每个请求都能正确处理。
- 模拟私有方法: 由于 JavaScript 中没有真正的私有方法,但使用闭包可以模拟私有方法。通过在对象中创建闭包作为方法,可以将外部无法直接访问的方法包装在闭包中,实现私有性。
- 实现记忆化: 闭包可以用于实现记忆化,即将函数的输入和输出进行缓存,以便在相同输入的情况下直接返回缓存的结果,提高函数执行效率。
这些案例只是闭包在实际应用中的几个例子,闭包的灵活性使其适用于各种场景。通过合理运用闭包,我们可以更好地组织和管理代码,提高代码的可读性和可维护性,并实现一些有趣和强大的功能。
学习资源推荐
-
文章和教程:
MDN Web 文档:MDN 提供了详细的闭包介绍和示例,是一个很好的起点。
JavaScript 高级概念:闭包:阮一峰的博客文章,对闭包进行了深入讲解,适合进一步理解闭包的原理和应用。
廖雪峰的 JavaScript 教程:廖雪峰的 JavaScript 教程也涵盖了闭包的内容,以简洁明了的方式介绍了闭包的原理和使用方法。
慕课网:慕课网是国内知名的在线教育平台,提供了大量与 JavaScript 闭包相关的视频教程,如《JavaScript深入浅出》、《JavaScript进阶篇》等。
尚硅谷:尚硅谷是国内知名的IT培训机构,他们的网站上有大量 JavaScript 相关的教程和课程,包括闭包的讲解。 -
视频教程:
JavaScript Closures:Kyle Robinson Young 的视频教程,通过实际案例演示了闭包的功能和实际应用。
但需要注意,这边需要一个加速器,否则无法打开国外的网站,这就需要各位科学上网了。 -
书籍:
《JavaScript高级程序设计》(第4版):这本由 Nicholas C. Zakas 所著的书籍是学习 JavaScript 的经典之作,其中有一章专门讲解了函数和闭包。
《你不知道的JavaScript(上卷)》:这本由 Kyle Simpson 所著的系列图书中,第一卷涵盖了 JavaScript 的作用域和闭包,对深入理解闭包非常有帮助。
除了这些资源之外,还建议你通过实际编写代码和阅读开源项目的源代码来进一步学习闭包。实践中遇到的问题和案例可以帮助加深对闭包的理解和应用。
记住,理解闭包需要时间和实践。持续阅读和编写代码将帮助你更好地掌握闭包的概念和技巧。

相关文章:
前端(十三)——JavaScript 闭包的奥秘与高级用法探索
😶博主:小猫娃来啦 😶文章核心:深入理解 JavaScript 中的闭包 文章目录 不理解闭包?这玩意很难?闭包的定义与原理闭包是什么创建一个闭包 闭包的应用场景闭包与作用域闭包与作用域之间的关系全局作用域、函…...
面试-快速学习计算机网络-UDP/TCP
1. OSI四层和七层映射 区别: 应用层,表示层,会话层合并为了应用层数据链路层和物理层合并为了网络接口层 2. TCP和UDP的区别? 总结: 1 . TCP 向上层提供面向连接的可靠服务 ,UDP 向上层提供无连接不可靠服…...
爱校对如何帮助企业和博客主提高在线可见性?
在数字化时代,内容质量已经成为增强在线曝光率的关键因素。企业和博客主经常面临挑战,如何制作高质量、无误的内容以吸引更多的在线用户。此文将详细分析“爱校对”如何帮助用户优化内容,从而提高在线可见性。 1.互联网内容的挑战 搜索引擎…...
MATLAB中xlsread函数用法
目录 语法 说明 示例 将工作表读取到数值矩阵 读取元胞的范围 读取列 请求数值、文本和原始数据 对工作表执行函数 请求自定义输出 局限性 xlsread函数的功能是读取Microsoft Excel 电子表格文件 语法 num xlsread(filename) num xlsread(filename,sheet) num x…...
Prisma.js:JavaScript中的基于代码的ORM
Prisma是一种流行的用于服务器端JavaScript和TypeScript的数据映射层(ORM)。它的核心目的是简化和自动化数据在存储和应用程序代码之间的传输方式。Prisma支持各种数据存储,并为数据持久化提供了一个强大而灵活的抽象层。通过这个基于代码的…...
解决问题:在cocos create中如何从b文件调用到a文件里用CC.resource.load动态加载的图集
目录 1.在a文件中定义一个公共的变量存储动态加载的图集 2.在a.js中添加一个静态方法,返回动态加载的图集 3.在b.js中使用a.js中定义的静态方法获取图集,并使用它 假设a文件中用CC.resource.load动态加载了一张图集,b文件需要使用这张图集&am…...
分布式 - 消息队列Kafka:Kafka 消费者消费位移的提交方式
文章目录 1. 自动提交消费位移2. 自动提交消费位移存在的问题?3. 手动提交消费位移1. 同步提交消费位移2. 异步提交消费位移3. 同步和异步组合提交消费位移4. 提交特定的消费位移5. 按分区提交消费位移 4. 消费者查找不到消费位移时怎么办?5. 如何从特定…...
如何利用 ChatGPT 进行自动数据清理和预处理
推荐:使用 NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 ChatGPT 已经成为一把可用于多种应用的瑞士军刀,并且有大量的空间将 ChatGPT 集成到数据科学工作流程中。 如果您曾经在真实数据集上训练过机器学习模型,您就会知道数据清理和预…...
PHP“牵手”淘宝商品评论数据采集方法,淘宝API接口申请指南
淘宝天猫商品评论数据接口 API 是开放平台提供的一种 API 接口,它可以帮助开发者获取商品的详细信息,包括商品的标题、描述、图片等信息。在电商平台的开发中,详情接口API是非常常用的 API,因此本文将详细介绍详情接口 API 的使用…...
你更喜欢哪一个:VueJS 还是 ReactJS?
观点列表: 1、如果你想在 HTML 中使用 JS,请使用 Vue; 如果你想在 JS 中使用 HTML,请使用 React。 当然,如果您希望在 JS 中使用 HTML,请将 Vue 与 JSX 结合使用。 2、Svelte:我喜欢它&#…...
PyTorch学习笔记(十六)——利用GPU训练
一、方式一 网络模型、损失函数、数据(包括输入、标注) 找到以上三种变量,调用它们的.cuda(),再返回即可 if torch.cuda.is_available():mynn mynn.cuda() if torch.cuda.is_available():loss_function loss_function.cuda(…...
【实战】十一、看板页面及任务组页面开发(三) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(二十五)
文章目录 一、项目起航:项目初始化与配置二、React 与 Hook 应用:实现项目列表三、TS 应用:JS神助攻 - 强类型四、JWT、用户认证与异步请求五、CSS 其实很简单 - 用 CSS-in-JS 添加样式六、用户体验优化 - 加载中和错误状态处理七、Hook&…...
金额千位符自定义指令
自定义指令文件 moneyFormat.js /*** v-money 金额千分位转换*/export default {inserted: inputFormatter({// 格式化函数formatter(num, util) {if(num null || num || num undefined || typeof(num) undefined){return }if(util 万元 || util 万){return formatMone…...
请不要用 JSON 作为配置文件,使用JSON做配置文件的缺点
我最近关注到有的项目使用JSON作为配置文件。我觉得这不是个好主意。 这不是JSON的设计目的,因此也不是它擅长的。JSON旨在成为一种“轻量级数据交换格式”,并声称它“易于人类读写”和“易于机器解析和生成”。 作为一种数据交换格式,JSON是…...
Hadabot:从网络浏览器操作 ROS2 远程控制器
一、说明 Hadabot Hadabot是一个学习ROS2和机器人技术的机器人套件。使用 Hadabot,您将能够以最小的挫败感和恐吓来构建和编程物理 ROS2 机器人。Hadabot套件目前正在开发中。它将仅针对ROS2功能,并强调基于Web的用户界面。 随着开发的进展&a…...
Kotlin 协程
Kotlin 协程(Coroutines)是一种轻量级的并发编程解决方案,旨在简化异步操作和多线程编程。它提供了一种顺序和非阻塞的方式来处理并发任务,使得代码可以更加简洁和易于理解。Kotlin 协程通过提供一套高级 API,使并发代…...
maven 从官网下载指定版本
1. 进入官网下载页面 Maven – Download Apache Maven 点击下图所示链接 2. 进入文件页,选择需要的版本 3. 选binaries 4. 选文件,下载即可...
数据结构---串(赋值,求子串,比较,定位)
目录 一.初始化 顺序表中串的存储 串的链式存储 二.赋值操作:将str赋值给S 链式表 顺序表 三.复制操作:将chars复制到str中 链式表 顺序表 四.判空操作 链式表 顺序表 五.清空操作 六.串联结 链式表 顺序表 七.求子串 链式表 顺序表…...
WPF CommunityToolkit.Mvvm
文章目录 前言ToolkitNuget安装简单使用SetProperty,通知更新RealyCommandCanExecute 新功能,代码生成器ObservablePropertyNotifyCanExecuteChangedForRelayCommand其他功能对应关系 NotifyPropertyChangedFor 前言 CommunityToolkit.Mvvm(…...
Vue开发中如何解决国际化语言切换问题
Vue开发中如何解决国际化语言切换问题 引言: 在如今的全球化时代,应用程序的国际化变得越来越重要。为了让不同地区的用户能够更好地使用应用程序,我们需要对内容进行本地化,以适应不同语言和文化环境。对于使用Vue进行开发的应用…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
