JS中的闭包
2022/4/18 23:43:33
本文主要是介绍JS中的闭包,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
JS中的闭包
- 引入
需求: 点击某个按钮, 提示"点击的是第 n 个按钮"
var btns = document.getElementsByTagName('button') for (var i = 0,length=btns.length; i < length; i++) { var btn = btns[i] //将btn所对应的下标保存在btn上 btn.index = i btn.onclick = function () { alert('第'+(this.index+1)+'个') } } //利用闭包 for (var i = 0,length=btns.length; i < length; i++) { (function (j) { var btn = btns[j] btn.onclick = function () { alert('第'+(j+1)+'个') } })(i) }
- 如何产生闭包?
- 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
- 函数嵌套
- 内部函数引用了外部函数的数据(变量/函数)
- 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
- 闭包到底是什么?
- 理解一: 闭包是嵌套的内部函数(绝大部分人)
- 理解二: 包含被引用变量(函数)的对象(极少数人)
- 注意: 闭包存在于嵌套的内部函数中
- 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 常见闭包
-
- 将函数作为另一个函数的返回值
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f();
-
- 将函数作为实参传递给另一个函数调用
function showDelay(msg, time) { setTimeout(function () { alert(msg) }, time) } showDelay('atguigu', 2000)
-
- 闭包的作用:
- 使用函数内部的变量在函数执行完后, 仍然存活在内存中(延长了局部变量的生命周期)
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
- 函数执行完后, 函数内部声明的局部变量是否还存在? //一般是不存在, 存在于闭中的变量才可能存在
- 在函数外部能直接访问函数内部的局部变量吗? //不能, 但我们可以通过闭包让外部操作它
- 闭包的生命周期
- 产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)
- 死亡: 在嵌套的内部函数成为垃圾对象时,
f = null
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
(function (window) { //私有的数据 var msg = 'atguigu' var names = ['I', 'Love', 'you'] //操作数据的函数 function a() { console.log(msg.toUpperCase()) } function b() { console.log(names.join(' ')) } window.coolModule2 = { doSomething: a, doOtherthing: b }
})(window)
* 循环遍历加监听 * JS框架(jQuery)大量使用了闭包 * 缺点: * 变量占用内存的时间可能会过长 * 可能导致内存泄露 * 解决: * 及时释放 : f = null; //让内部函数对象成为垃圾对象 ************* ## 面试题 * 1. ```js //代码片段一 var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //? the window //代码片段二 var name2 = "The Window"; var object2 = { name2 : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name2; }; } }; alert(object2.getNameFunc()()); //? my object
function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n) } } } var a = fun(0) a.fun(1) a.fun(2) a.fun(3)//undefined,0,0,0 var b = fun(0).fun(1).fun(2).fun(3)//undefined,0,1,2 var c = fun(0).fun(1) c.fun(2) c.fun(3)//undefined,0,1,1
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
// 1. 内存溢出 var obj = {} for (var i = 0; i < 10000; i++) { obj[i] = new Array(10000000) console.log('-----') } // 2. 内存泄露 // 意外的全局变量 function fn() { a = new Array(10000000) console.log(a) } fn() // 没有及时清理的计时器或回调函数 var intervalId = setInterval(function () { //启动循环定时器后不清理 console.log('----') }, 1000) // clearInterval(intervalId) // 闭包 function fn1() { var a = 4 function fn2() { console.log(++a) } return fn2 } var f = fn1() f() // f = null
这篇关于JS中的闭包的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-04React 19 来了!新的编译器简直太棒了!
- 2025-01-032025年Node.js与PHP大比拼:挑选最适合的后端技术进行现代web开发
- 2025-01-03?? 用 Gemini API、Next.js 和 TailwindCSS 快速搭建 AI 推文生成项目 ??
- 2024-12-31Vue CLI多环境配置学习入门
- 2024-12-31Vue CLI学习入门:一步一步搭建你的第一个Vue项目
- 2024-12-31Vue3公共组件学习入门:从零开始搭建实用组件库
- 2024-12-31Vue3公共组件学习入门教程
- 2024-12-31Vue3学习入门:新手必读教程
- 2024-12-31Vue3学习入门:初学者必备指南
- 2024-12-30Vue CLI多环境配置教程:轻松入门指南