閉包
- 閉包是指函數內部引用了外部的變量,而外部變量的值是可變化的,閉包里的引用的值是隨外部變化的。---
- 閉包允許你引用存在于外部函數中的變量。然而,它并不是使用該變量創建時的值,相反,它使用外部函數中該變量最后的值。
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); //引用了外部的函數,導致
}
outter.push(x);
}
}
//調用這個函數
clouseTest();
print(outter[0].invoke());
print(outter[1].invoke());
print(outter[2].invoke());
print(outter[3].invoke());
- 這個立即執行函數解決了 閉包的問題,因為立即執行函數的參數傳值是 按值傳遞的,可理解為,變量已經被賦值了另一份給到函數體內保存。
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)
柯里化(英語:Currying),又譯為卡瑞化或加里化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數而且返回結果的新函數的技術。
所謂"柯里化",就是把一個多參數的函數,轉化為單參數函數。
// 柯里化之前
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)
如果一個值要經過多個函數,才能變成另外一個值,就可以把所有中間步驟合并成一個函數,這叫做"函數的合成"(compose)。
合成的好處顯而易見,它讓代碼變得簡單而富有可讀性,同時通過不同的組合方式,我們可以輕易組合出其他常用函數,讓我們的代碼更具表現力。
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))