闭包是js学习中不能绕过去的一个坑,初学者一般都会问闭包到底有什么用呢,我们直接需要的时候定义一个变量它不香吗,为什么一定要把一个变量困住呢,还占用内存,但其实有很多例子中我们是非要用到闭包不可的。
一.闭包的概念
闭包就是在外部函数内部定义了内部函数,内部函数中引入了外部函数的局部变量,当外部函数执行完毕后,局部变量并不会被释放。将变量留在了内存中,将来可以使用。
二.闭包的重要应用
私有变量的实现
我们都知道在c中都是可以在构造函数内部构造私有变量的,但是在js中你会怎么办呢?有请闭包小姐:
//私有变量实现
function Person(_name,_age) {
this.name=_name;
let age =_age;
this.setAge=function() {
this.age = age;
}
this.getAge=function() {
return this.age;
}
}
let per = new Person('xpp',26);
per.setAge();
console.log(per.getAge())
DOM文档获取元素索引(解决ES5中没有块级作用域问题)
先看没有使用闭包时的代码:
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
window.onload=function () {
let ul = document.querySelectorAll('li')
for(var i=0;i<3;i++){
ul[i].onclick = function () {
alert(i);
}
}
}
</script>
</body>
会发现不管你点击哪一个元素弹出来的都是3.这是因为在ES6之前并没有块级作用域,i是一个全局变量,当页面加载完成时for循环已经执行完了,所以不管点击哪个结果都是3,下面我们看使用了闭包后的代码:<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
window.onload=function () {
let ul = document.querySelectorAll('li')
for(var i=0;i<3;i++){
(function set(j){
ul[j].onclick = function () {
alert(j);
}
})(i)
}
}
</script>
</body>
就可以正常获得DOM元素的索引值了,因为闭包的存在,所以函数的局部变量不能被释放闭包实现计时器传参效果
function fn(data) {
return function () {
console.log(data)
}
}
let f1=fn('xpp');
setTimeout(f1,100)
闭包实现模块化统计用于点击量功能
function Tracker() {
var accessCounter = 0;
var accessAd = [];
return {
accessAdd:function (page) {
accessAd.push(page)
},
getAccessAd:function () {
return accessAd;
},
addAccessCounter:function () {
accessCounter++;
},
getAccessCounter:function () {
return accessCounter;
}
}
}
let track = Tracker();
track.addAccessCounter();
console.log(track.getAccessCounter())