閉包
- 閉包是指函數(shù)內(nèi)部引用了外部的變量,而外部變量的值是可變化的,閉包里的引用的值是隨外部變化的。---
- 閉包允許你引用存在于外部函數(shù)中的變量。然而,它并不是使用該變量創(chuàng)建時(shí)的值,相反,它使用外部函數(shù)中該變量最后的值。
var outter = [];
function clouseTest () {
var array = ["one", "two", "three", "four"];
for(var i = 0; i < array.length;i++){
var x = {};
x.no = i;
x.text = array[i];
x.invoke = function(){
print(i); //引用了外部的函數(shù),導(dǎo)致
}
outter.push(x);
}
}
//調(diào)用這個(gè)函數(shù)
clouseTest();
print(outter[0].invoke());
print(outter[1].invoke());
print(outter[2].invoke());
print(outter[3].invoke());
- 這個(gè)立即執(zhí)行函數(shù)解決了 閉包的問(wèn)題,因?yàn)榱⒓磮?zhí)行函數(shù)的參數(shù)傳值是 按值傳遞的,可理解為,變量已經(jīng)被賦值了另一份給到函數(shù)體內(nèi)保存。
function clouseTest2(){
var array = ["one", "two", "three", "four"];
for(var i = 0; i < array.length;i++){
var x = {};
x.no = i;
x.text = array[i];
x.invoke = function(no){
return function(){
print(no);
}
}(i); //這里它是按值傳遞的。
outter.push(x);
}
}
柯里化(Currying)
柯里化(英語(yǔ):Currying),又譯為卡瑞化或加里化,是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。
所謂"柯里化",就是把一個(gè)多參數(shù)的函數(shù),轉(zhuǎn)化為單參數(shù)函數(shù)。
// 柯里化之前
function add(x, y) {
return x + y;
}
add(1, 2) // 3
// 柯里化之后
function addX(y) {
return function (x) {
return x + y;
};
}
addX(2)(1) // 3
合成(compose)
如果一個(gè)值要經(jīng)過(guò)多個(gè)函數(shù),才能變成另外一個(gè)值,就可以把所有中間步驟合并成一個(gè)函數(shù),這叫做"函數(shù)的合成"(compose)。
合成的好處顯而易見(jiàn),它讓代碼變得簡(jiǎn)單而富有可讀性,同時(shí)通過(guò)不同的組合方式,我們可以輕易組合出其他常用函數(shù),讓我們的代碼更具表現(xiàn)力。
function f1(arg) {
console.log("f1", arg);
return arg;
}
function f2(arg) {
console.log("f2", arg);
return arg;
}
function f3(arg) {
console.log("f3", arg);
return arg;
}
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
let res = compose(f1, f2, f3)("omg"); //f1(f2(f3("omg")));
console.log("res", res); //sy-log
另一種更好理解的compose
const compose = (...[first, ...second]) => args => {
let ret = first(args);
second.forEach(( fn )=>{
ret = fn(ret);
})
return ret;
}
const fn = compose(add,square)
console.log(fn(1, 2))