JS 闭包 实现原理 使用闭包的意义
- 静态作用域 又叫 词法作用域(Lexcical Scope): 在编译时就确定了作用域范围;
- 动态作用域:变量引用跟变量声明不是在编译时就绑定死了的。在运行时,它是在运行环境中动态地找一个相同名称的变量。
js 属于函数式编程。
闭包
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这种组合就是闭包。
闭包让你可以在一个内层函数中访问到其外层函数的作用域
只要函数能作为值传来传去(高阶函数),就一定会产生作用域不匹配的情况,这样的内在矛盾是语言设计时就决定了的。
可以认为闭包是为了让函数能够在这种情况下继续运行所提供的一个方案。
正因为这些数据只能被闭包函数访问,所以也就具备了对信息进行封装、隐藏内部细节的特性。
简单计数器案例
let add = function() {
let counter = 0
return () => counter++
}
add() // 1
add() // 2
add = null // 手动释放闭包
本方法既实现了任何地方都能访问 counter
,但又只能通过 add
全局变量能够通过闭包实现局部(私有)。
拥有相同名称的全局变量和闭包中的局部变量是不同的变量
全局变量,任何代码都可以更改全局变量,而无需调用函数
闭包意义
JavaScript 模块化之前,可以利用闭包实现封装,实现类似私有变量的效果。
闭包使得可以全局访问 函数的私有变量 但只有提供的接口可以访问 避免了污染全局变量。
私有变量受匿名函数的作用域保护,处理不好会造成内存泄漏
闭包可用于封装一段代码
fengzhuang = (function() {
let a,b = 10,20;
function sub() {
return a + b;
}
function add() {
return a - b;
}
return {
add,
sub
}
})()
通过闭包参数i被保留下来
// 可以一次打印i
for (var i = 0; i < 4; i++) {
(function (i) {
setTimeout(function () {
console.log(i)
}, 0)
})(i)
}
循环绑定事件
var a = document.getElementsByTagName("a");
for(var i =0; i<a.length; i++){
a[i].onclick = (function(i){
return function(){alert(i);}
})(i);
}
闭包和对象在底层上是存在相似性的
构造函数中避免使用闭包,应通过原型中注册方法的方式
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype.getName = function() {
return this.name;
};
MyObject.prototype.getMessage = function() {
return this.message;
};
内容会不断更新,欢迎批评指正。
分类:
# JavaScript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix