JS如下闭包代码(局部变量计数)如何理解
<!DOCTYPEhtml><html><head><metacharset="utf-8"><title></title></head><body><p>局部变量计数。...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>局部变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
不明白:每次调用add的时候不都是先给counter赋值0吗,为什么返回时counter的值不是恒为1,而是逐渐递加?每次调用add函数时,变量的变化是怎样的?
我的理解是:add() 展开
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>局部变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
不明白:每次调用add的时候不都是先给counter赋值0吗,为什么返回时counter的值不是恒为1,而是逐渐递加?每次调用add函数时,变量的变化是怎样的?
我的理解是:add() 展开
展开全部
先将代码改写为
var add = (function () {
var counter = 0;
console.log('a'+counter);
return function () {
console.log('b'+counter);
return counter += 1;
}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
当第一次执行的时候输出a0.
当点击按钮之后输出输出b0 b1 b2 b3......
这时候你会发现这段代码只执行了function () {
console.log('b'+counter);
return counter += 1;
}
这部分。
自此为止,答案就出来了 ,自执行(function () {})()返回结果为function () {
console.log('b'+counter);
return counter += 1;
}既 var add=function () {
console.log('b'+counter);
return counter += 1;
}
而counter 在自执行方法里已经设置并被保存,所以是累计而非恒定。
展开全部
这么和你说吧,这个就是闭包的最经典的例子,为什么counter不会被清0呢,首先楼主应该明白全局变量的概念,当全局变量被定义以后,不管执行什么运算,全局变量最后的结果都会被保存在内存中不会被初始化对吧。
然后我们来看看这个闭包,在add方法中,我们先对counter赋了一个初始值0,然后return了一个function ,此时这个function相当于add方法的子方法,此时由于counter在子方法外,所以相对于子方法,counter这个变量是一个全局变量,所以在子方法中,counter会被保存在内存中,不会被垃圾回收机制清空,而子方法依赖于父方法add,因此导致父方法中的counter也不会被垃圾回收机制从内存中清除,这样就使得counter会相当于一个全局变量一直递增,这样说你明白了吗。
然后我们来看看这个闭包,在add方法中,我们先对counter赋了一个初始值0,然后return了一个function ,此时这个function相当于add方法的子方法,此时由于counter在子方法外,所以相对于子方法,counter这个变量是一个全局变量,所以在子方法中,counter会被保存在内存中,不会被垃圾回收机制清空,而子方法依赖于父方法add,因此导致父方法中的counter也不会被垃圾回收机制从内存中清除,这样就使得counter会相当于一个全局变量一直递增,这样说你明白了吗。
追问
看了您的回答,我是这样理解:在子方法中,counter会储存在内存中,即子方法中counter就是一个全局变量,然后add中的counter其实还是一个局部变量,无论如何给它赋值,都不会影响全局变量。第一次调用add方法时创建了一个局部变量,也创建了子方法中的全局变量,之后add中的变量和子方法中的变量相当于是两个不同的变量,所以子方法中的全局变量counter会递增。
追答
实际上add里面的counter只会在第一次被初始化,接下来var counter=0;都是没有用的
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询