最近看JavaScript有关闭包的知识分享给大家
一、闭包是什么?
闭包指的是有权访问另一个函数作用域中变量的函数,一个作用域可以访问另一个函数内部的局部变量,简单来说就是函数嵌套函数内部函数就是闭包。
例如:
function fn() {
var a = 10;
function fn1() {
console.log('a的值:' + a);
}
fn1();
}
fn();
解析:
我们可以看到我们能把a的值打印出来,说明这里fn1可以使用a这个变量,也就是说在fn1函数的作用域里面我们可以访问fn函数作用域中的局部变量a,此时满足了闭包的条件就产生了闭包,我们可以在chrome里面打断点调试看我们的闭包有没有产生。这里的断点我打在fn()这行代码上。
当我们走到fn1这个函数里面的时候,我们发现在Scope里面多了一个参数Closure这个就是闭包的意思,fn1可以访问fn内部的局部变量,fn函数嵌套fn1函数符合闭包定义,所以这里fn1就是一个闭包。
二、闭包的作用
在全局作用域下也可以访问一个函数内部的局部变量
例如:
function fn() {
var a = 10;
return function(){
console.log('a的值为:'+a);
}
}
// 下面代码相当于
// var b = function(){
// console.log('a的值为:'+a);
// }
var b = fn();
b();
解析:
运行代码我们发现这里也可以输出a的值,执行代码var b = fn();就相当于声明了变量b等于返回过来的函数,所以可以用b();来调用。在Chrome查看,这次断点打在var b = fn();上
原本一个函数内部有一个局部变量,当这个函数执行完就会销毁,但是现在fn()执行完不会销毁,不会被垃圾回收,因为还有b变量要调用这个a,只有b也调用完了才会销毁,所以闭包的主要作用是延伸了变量的作用范围。
二、闭包的应用
我们来看一个闭包实际应用的例子,点击li输出索引号,传统方法可以使用动态添加li的index属性来完成,现在我们要用闭包来做。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
/* 清除默认样式 */
margin: 0;
padding: 0;
}
.nav {
/* flex布局 */
display: flex;
}
.nav li {
width: 50px;
height: 50px;
margin-right: 10px;
background-color: skyblue;
list-style: none;
}
</style>
</head>
<body>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var lis = document.querySelector('.nav').querySelectorAll('li');
// 传统方法利用动态添加属性的方式
// for (var i = 0; i < lis.length; i++) {
// lis[i].index = i;
// lis[i].onclick = function() {
// // console.log(i);
// console.log(this.index);
// }
// }
// 利用闭包的方式
for (var i=0;i<lis.length;i++){
(function(i){
// 立即执行函数里面嵌套了一个函数,并且使用了立即执行函数里面的变量i所以这里产生了闭包
lis[i].onclick = function(){
console.log(i);
}
})(i);
}
</script>
</body>
</html>
输出结果可以看到我们利用闭包也是可以实现的。
总结
以上就是今天要跟大家分享的JS闭包的相关知识。