返回

JavaScript闭包

发布时间:2022-11-03 23:42:36 297

闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。 闭包是 JavaScript 语言的一大特点,主要应用闭包场合主要是为了:设计私有的方法和变量。

闭包的几种表现形式

  1. 返回一个函数
  2. 作为函数参数传递
  3. 回调函数
  4. 非典型闭包IIFE(立即执行函数表达式)

返回一个函数:这种形式的闭包在​​JavaScript​​的代码编写中,是非常常见的一种方式。

 

var a  = 1;
function foo(){
var a = 2;
// 这就是闭包
return function(){
console.log(a);
}
}
var bar = foo();
// 输出2,而不是1
bar();

 

作为函数参数传递:无论通过何种手段将内部函数传递到它所在词法作用域之外,它都会持有对原始作用域的引用,无论在何处执行这个函数,都会产生闭包。

 

var a = 1;
function foo(){
var a = 2;
function baz(){
console.log(a);
}
bar(baz);
}
function bar(fn){
// 这就是闭包
fn();
}
// 输出2,而不是1
foo();

 

回调函数:在定时器、事件监听、Ajax请求、跨窗口通信、Web Workers或者任何异步中,只要使用了回调函数,实际上就是在使用闭包。

 

// 定时器
setTimeout(function timeHandler(){
console.log('timer');
},100)

// 事件监听
$('#container').click(function(){
console.log('DOM Listener');
})

 

IIFE:IIFE(立即执行函数表达式)并不是一个典型的闭包,但它确实创建了一个闭包。

 

var a = 2;
(function IIFE(){
// 输出2
console.log(a);
})();

 

经典循环和闭包面试题

以下代码运行结果是什么,如何改进?

 

for(var i=1;i<=5;i++){
setTimeout(function timer(){
console.log(i)
}, i*1000)
}

 

代码分析

  1. ​for​​循环创建了5个定时器,并且定时器是在循环结束后才开始执行
  2. ​for​​​循环结束后,用​​var i​​​定义的变量​​i​​此时等于6
  3. 依次执行五个定时器,都打印变量​​i​​,所以结果是打印5次6

第一种改进方法:利用​​IIFE(立即执行函数表达式)​​​当每次​​for​​​循环时,把此时的​​i​​变量传递到定时器中

 

for(var i=1;i<=5;i++){
(function(j){
setTimeout(function timer(){
console.log(j)
}, i*1000)
})(i)
}

 

第二种方法:​​setTimeout​​函数的第三个参数,可以作为定时器执行时的变量进行使用

 

for(var i=1;i<=5;i++){
setTimeout(function timer(j){
console.log(j)
}, i*1000, i)
}

 

第三种方法(推荐):在循环中使用​​let i​​​代替​​var i​

 

for(let i=1;i<=5;i++){
setTimeout(function timer(){
console.log(i)
}, i*1000)
}

 

 

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
JDK8 HashMap如何实现? 2022-11-03 23:19:15