<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>閉包</title>
</head>
<body>
</body>
<script>
//子函數(shù)可以訪問到父級函數(shù)的作用域鸟妙,這種現(xiàn)象稱為閉包
let arr=[1,23,4,6,17,3,10,2,5,7,9];
//選出5到9之間的數(shù)
let a=arr.filter(function(v){
return v>=5&&v<=9;
});
console.log(a);
//選出3到7之間的數(shù)
let b=arr.filter(function(v){
return v>=3&&v<=7;
});
console.log(b);
//考慮函數(shù)復用,子函數(shù)可以return父級作用域的某些數(shù)據(jù),這是閉包的一個很大的特性
function between(a,b){
return function(v){
return v>=a&&v<=b;
}
}
let c=arr.filter(between(2,8));
console.log(c);
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>移動動畫的閉包使用</title>
</head>
<style>
button{
position: absolute;
left:0;
}
</style>
<body>
<button>hao</button>
<button>yangdingchuan</button>
</body>
<script>
let btns=document.querySelectorAll('button');
[...btns].forEach(function(item){
let left=1;
let sitid=false;
item.addEventListener('click',function(e){
//問題一妹蔽、如果left在這里定義,點擊第二次時會出現(xiàn)抖動姜挺,因為每次點擊都會觸發(fā)使left重新定義
//解決辦法是把left放到點擊事件外部定義
//let left=1;
//問題二、left放到點擊事件外部定義辜王,解決了抖動但是會在每次點擊都會加速按鈕的移動
//因為每次點擊都會重新創(chuàng)建一個定時器逢唤,這樣點擊10次就是創(chuàng)建10個定時器肆氓,不是每100ms的速度移動了
//而成了每10ms自增的速度了
/* setInterval(function(){
item.style.left=`${left++}px`;
},100); */
//解決辦法:存一個標志,如果定時器已經建立了就不在重復創(chuàng)建了
if(sitid==false){
sitid=true;
setInterval(function(){
item.style.left=`${left++}px`;
},100);
}
});
});
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>利用閉包根據(jù)字段排序商品</title>
</head>
<body>
</body>
<script>
let goods=[
{
name:'banana',
price:10,
click:30
},
{
name:'apple',
price:5,
click:40
},
{
name:'grape',
price:15,
click:32
}
];
//按價格升序
let g0=goods.sort(function(a,b){
return a.price>b.price?1:-1;
});
console.log(g0);
//按點擊次數(shù)降序
let g1=goods.sort(function(a,b){
return a.click<b.click?1:-1;
});
console.log(g1);
//考慮代碼復用
function order(field){
return function(a,b){
//升序
return a[field]>b[field]?1:-1;
//降序
//return a[field]<b[field]?1:-1;
}
}
let g2=goods.sort(order("price"));
console.log(g2);
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>閉包的內存泄露解決辦法</title>
</head>
<body>
<div name='haoxuejie'>郝雪潔</div>
<div name='yangdingchuan'>楊定川</div>
</body>
<script>
let divs=document.querySelectorAll("div");
/* [...divs].forEach(function(item){
item.addEventListener('click',function(){
console.log(item.getAttribute('name'));
console.log(item);
});
//每次都會在內存中存大量的dom節(jié)點怖辆,
//如果dom元素內容比較多是复,會引起內存泄露
}); */
//改進辦法
[...divs].forEach(function(item){
let name=item.getAttribute('name');
item.addEventListener('click',function(){
console.log(name);
console.log(item);//null
});
item=null;//及時清理內存,可以使程序運行更快一些
});
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>this在閉包中的歷史遺留問題</title>
</head>
<body>
</body>
<script>
let hxj={
user:"haoxuejie",
get:function(){
return this.user;
},
get0:function(){
return function(){
return this.user;
}
},
get1:function(){
return ()=>{
return this.user;
}
}
};
let h=hxj.get();
console.log(h);//haoxuejie
let x=hxj.get0();
console.log(x);//是一個函數(shù)
console.log(x());//undefined,因為此時x是全局對象竖螃,它的this指向的是window,window里面沒有user這個變量
//使用箭頭函數(shù)解決上述問題,get1()內部定義的返回函數(shù)是使用箭頭函數(shù)定義的
let j=hxj.get1();
console.log(j);//輸出一個箭頭函數(shù)
console.log(j());//haoxuejie
</script>
</html>