1.高階函數(shù)
? ? ? ?函數(shù)當(dāng)參數(shù),把傳入的函數(shù)做一個(gè)封裝,然后返回這個(gè)封裝函數(shù)目锭,達(dá)到更高程度的抽象。
??
//命令式
var add = function(a,b){
return a + b;
};
function math(func,array){
return func(array[0],array[1]);
}
math(add,[1,2]);//3
2.尾調(diào)用優(yōu)化
? ? ? ?尾調(diào)用是函數(shù)式編程的一個(gè)重要概念纷捞。
? ? ? ?指函數(shù)內(nèi)部的最后一個(gè)動(dòng)作是函數(shù)調(diào)用痢虹。該調(diào)用的返回值,直接返回給函數(shù)主儡。函數(shù)調(diào)用自身奖唯,稱為遞歸。如果尾調(diào)用自身糜值,就稱為尾遞歸丰捷。遞歸需要保存大量的調(diào)用記錄,很容易發(fā)生棧溢出錯(cuò)誤寂汇,如果使用尾遞歸優(yōu)化病往,將遞歸變?yōu)檠h(huán),那么只需要保存一個(gè)調(diào)用記錄骄瓣,這樣就不會(huì)發(fā)生棧溢出錯(cuò)誤了停巷。
? ? ? ?尾調(diào)用優(yōu)化的意義是大大節(jié)省內(nèi)存。
? ? ? ?尾調(diào)用模式只在嚴(yán)格模式下生效榕栏。
??
function factorial(n){
if(n === 1) return 1;
return n*factorial(n-1);
}
factorial(5);//120
function factorial(n,total){
if(n === 1) return total;
return factorial(n-1,n*total);
}
factorial(5,1);//120
3.閉包
? ? ? ?首先要清楚畔勤,js是函數(shù)級(jí)別的作用域。這個(gè)級(jí)別的作用域扒磁,函數(shù)里面的變量外面是無(wú)法獲取的庆揪,如果處于某種原因需要得到函數(shù)內(nèi)部的變量怎么辦,兩種方式妨托,第一缸榛,直接把值return出去,但是直接return出去兰伤,那這個(gè)值就和函數(shù)內(nèi)部沒(méi)有什么關(guān)聯(lián)了内颗。第二,如果還想和內(nèi)部產(chǎn)生關(guān)聯(lián)的話医清,就再包一層function起暮,這樣這個(gè)function就能夠保存到這個(gè)變量在內(nèi)存中。
??
//第一種方式
function s(){
var a = 1;
return a;
}
var p = s();
p++;
//把a(bǔ)直接return出來(lái),然后再p++负懦,但是p++已經(jīng)和變量a沒(méi)有任何關(guān)系了筒捺。
//第二種方式
//函數(shù)s2可以讀取s中的變量,只要把s2作為返回值纸厉。就可以在s外部讀取它的內(nèi)部變量了系吭!
function s(){
var a = 1;
return function s2(){
return a;
};
}
var p = s();
p();
至于這樣可以將變量始終到內(nèi)存中
??
function f1(){
var n = 999;
nAdd = function (){
n += 1;
}
return function f2(){
return n;
}
var result = f1();
result();//console.log(result())----999
nAdd();
result();//console.log(result())-----1000
}
//這證明,函數(shù)f1中的局部變量n在f1執(zhí)行完之后沒(méi)有被清除颗品,而是一直保存在內(nèi)存中肯尺。