闭包(英文:closure)
1. 闭包是一个函数与作用域环境(即 词法环境)形成的闭包**
2. 闭包的理解:
广义的闭包:1.函数 2.这个函数能访问到函数外部的状态(也称函数外部的变量)
并不是我们平时理解的闭包:函数嵌套函数,并且内部函数通过return返回到外部,外部可以访问内部函数的变量
总结:闭包=函数+自由变量
自由变量:即可以是外部的变量,也可是父级函数的形参
闭包特点:
闭包中自由变量长期驻留内存,长期驻留内存中的变量如果处理不当,会导致内存泄露,不用的话要将闭包置为null
可以隔离作用域,模拟块级作用域
自由变量:就是在函数外部定义的,并且在函数内部可以访问到的变量就叫自由变量
one
<script>
var index = 1;
// 闭包特点:1.函数
// 2.这个函数能访问到函数外部的状态(也称函数外部的变量)
function getIndex(){
console.log(index) // 1
}
getIndex()
</script>
two
<script>
var index = 1
function getIndex(){
var index = 666
var a = 10
var b = 20
var c = 30
return function fn(){
index++
return index
}
}
var f1 = getIndex()
console.log(f1)
//ƒ fn(){
// index++
// return index
// }
console.log(f1()) // 667
console.log(f1()) // 668
console.log(f1()) // 669
f1 = null
</script>
three
<script>
// 要求每隔一秒打印1,2,3...10
// setTimeout是异步执行的,异步队列
for(var i = 0;i<=10;i++){
// 驻扎在内存中
(function(j){
setTimeout(function(){
console.log(j)
// 每隔一秒输出1,2,3...10
},1000*j)
})(i)
}
console.log(i) // 11
// 最直接的方法
for(let k = 0;k<=10;k++){
setTimeout(function(){
console.log(k)
},1000*k)
}
console.log(k) //i is not defined
</script>
four
<script>
// 函数表达式
// 功能:递增,递减,获取递增或递减之后的值
var Counter = function(){
// 私有变量
var num = 0
// 私有函数
var cahngeValue = function(n){
return num+=n
}
return {
// 增
add:function(){
cahngeValue(1)
},
// 减
reduce:function(){
cahngeValue(-1)
},
// 获取值
getValue:function(){
return num
}
}
}
var c1 = Counter()
c1.add() //1
c1.add() //2
c1.add() //3
c1.add() //4
c1.reduce() //4-1
console.log("c1的值:",c1.getValue()) // 3
var c2 = Counter()
c2.reduce()
c2.reduce()
console.log("c2:",c2.getValue()) // -2
</script>
five
<body>
<h2>通过闭包改变页面的字号</h2>
<div class="box">
<button>小号</button>
<button>中号</button>
<button>大号</button>
</div>
<p>特点:函数嵌套函数,并且内部函数通过return返回到外部,外部可以访问内部函数的变量</p>
<script>
function setSize(size){
return function(){
document.getElementsByTagName("p")[0].style.fontSize = size+'px'
}
}
var size14 = setSize(14)
var size40 = setSize(40)
var size50 = setSize(50)
function init(){
var btns = document.getElementsByTagName("button")
btns[0].onclick=size14
btns[1].onclick = size40
btns[2].onclick = size50
}
init()
</script>
</body>
six
<script>
var arr = []
for(var i = 0;i<5;i++){
arr[i]=(function(i){
return function(){
return i
}
})(i)
}
console.log(arr[0]()) //0
console.log(arr[1]()) //1
for(var j = 0;j<5;j++){
arr[j]=function(){
return j
}
}
console.log(arr[0]()) //5
console.log(arr[1]()) //5
</script>
seven
<div class="forms">
<p class="help">请移步光标选择你要输入的文本框</p>
<p>Email: <input type="text" id="email" name="emails"> </p>
<p>name: <input type="text" id="name" name="name"> </p>
<p>age: <input type="text" id="age" name="age"> </p>
</div>
<script>
function init(){
// 定义输入框提示的文字
var text = [
{id:'email',title:'请输入你的邮箱'},
{id:'name',title:'请输入你的名字'},
{id:'age',title:'请输入你的年龄'}
]
for(var i=0;i<text.length;i++){
var item = text[i]
document.getElementById(item.id).onfocus=(function(item){
return function() {
showText(item.title)
}
})(item)
}
}
function showText(title){
document.querySelector('.help').innerHTML = title
}
init()
</script>