閉包與柯里化、合成compose

閉包

  • 閉包是指函數內部引用了外部的變量,而外部變量的值是可變化的,閉包里的引用的值是隨外部變化的。---
  • 閉包允許你引用存在于外部函數中的變量。然而,它并不是使用該變量創建時的值,相反,它使用外部函數中該變量最后的值。
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());  
  1. 這個立即執行函數解決了 閉包的問題,因為立即執行函數的參數傳值是 按值傳遞的,可理解為,變量已經被賦值了另一份給到函數體內保存。
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))
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。