1 閉包(closure)
- 在函數(shù)的外部去訪問函數(shù)內(nèi)部的變量,這一種機(jī)制其實(shí)就是閉包
※※案例說明↓
var a = 0;
function f(){
var b = 1;
function f1(){
console.log(b++);
}
return f1;
}
var t = f();
t();
chrome下輸出的結(jié)果:1
簡單分析:函數(shù)f1()本身是定義在f()函數(shù)內(nèi)部 但是f1()去訪問了f()里面的b的變量,此時其實(shí)就形成了一個閉包;
1.1如何才能構(gòu)成一個閉包
- 在函數(shù)的內(nèi)部定義函數(shù)
2)函數(shù)內(nèi)部訪問它外部的變量(如同上面f1()要訪問f())
1.2 閉包的優(yōu)點(diǎn)
- 延長變量的生命周期
正常情況下一個函數(shù)的調(diào)用之后,它內(nèi)部定義的變量就會被刪除掉(被回收),但是使用閉包之后,它的生命周期就會得到延長
※※案例說明↓
var a = 0;
function f(){
var b = 1;
function f1(){
console.log(b++);
}
return f1();
}
var c = f();
c();
c();
c();
chrome下輸出的結(jié)果:1,2,3
1.3 閉包的缺點(diǎn)
閉包-內(nèi)存泄漏
※※案例一↓
function f(){
var a = 10;
function f1(){
console.log(a);
}
return f1;
}
var t = f();
t();
chrome下輸出的結(jié)果:10;
案例分析:
內(nèi)存泄漏.PNG
※※案例二↓
var a = [1,2,3,4];
function f(){
a = [];
}
f();
console.log(a);
chrome輸出的結(jié)果為空數(shù)組
案例分析:
1)a的右邊是一個應(yīng)用數(shù)據(jù)類型,
2)會在一個堆區(qū)里面開辟一個新的空間,用來存放數(shù)組里面的值
3)函數(shù)里面a的右邊是一個新的數(shù)組(空的數(shù)組)從而開辟了一個新的數(shù)組,使其引用地址在此時發(fā)生了改變
4)但是此時函數(shù)外面的a此時任然保存在堆區(qū)里面
鼠標(biāo)點(diǎn)擊案例(-閉包)
案例-鼠標(biāo)點(diǎn)擊事件
鼠標(biāo)點(diǎn)擊出現(xiàn)索引值.PNG
方法一
1)通過額外的添加一個自定義屬性,來保存 i 的值
添加自定義屬性.PNG
方法二
2)使用閉包
閉包-立即執(zhí)行函數(shù).PNG
案例分析:
① : f=function(){}就是一個閉包結(jié)構(gòu);
② : 它是一個函數(shù),它定義在另一個函數(shù)的內(nèi)部
③ : 它訪問的不是自己的變量-index
④ : 當(dāng)中加入了一個立即執(zhí)行函數(shù)(移步?立即執(zhí)行函數(shù)章節(jié))
⑤ : 函數(shù)的返回值會保存在btns[i]這個對象中的onclick屬性中
遞歸
語法結(jié)構(gòu):
在函數(shù)的內(nèi)部調(diào)用自己(自己調(diào)用自己)
※※案例↓
function f(){
console.log('f');
f();
}
f();
````
chrome下的結(jié)果:陷入死循環(huán)(棧溢出)
######遞:
遞進(jìn) : 把大問題分成小問題,一層一層向我們知道的那個答案靠近
######歸:
回歸 : 小問題都已經(jīng)得到了解決,從最小的問題向最大的問題回歸,一個個解決
※※案例一 >求多為數(shù)組中的元素的個數(shù)↓
````
<script>
var arr = [1,2,3,4,[56,45]];
function count(arr){
var sum = 0;
for (var i = 0; i < arr.length; i++) {
if(Array.isArray( arr[i] ) == false){
sum +=1;
}
else{
sum += count(arr[i]);
}
}
return sum;
}
console.info( count(arr) ) ;
</script>
````
chrome下輸出結(jié)果:6
案例分析:
1)遞歸調(diào)用的函數(shù)。
2)Count()的功能是:你給我一個數(shù)組,我告訴你它有幾個元素。
3)如果數(shù)組中的元素就是一個普通的元素(非數(shù)組的)則sum++即可。
4)如果數(shù)組中的元素又是一個數(shù)組,則需要遞歸調(diào)用count(當(dāng)前元素)
※※案例二 >循環(huán)與遞歸↓
````
<script>
//用循環(huán)來做
function f1(n){
var sum = 1;
for (var i = 1; i <= n; i++) {
sum *=i;
}
return sum;
}
//遞歸來做
function f2(n){
if(1== n){
return 1;
}
else
return f2(n-1) * n;
}
//算計(jì)時
function computerTime(f,n){
var t1 = new Date();
var result = f(n);
var t2 = new Date();
console.info("時間:"+ (t2-t1) + " 結(jié)果: "+result);
}
computerTime(f1,10000);
computerTime(f2,10000);
</script>
````
案例分析:
1) : 遞歸有最大的嵌套次數(shù)
2) : 可用用循環(huán)就不要用遞歸,一般來說,循環(huán)的效率比遞歸的效率更高一些
3) : 如果使用循環(huán)不能解決,再考慮用遞歸