對於這樣乙個函式:
function generate() ;
}
generate作為」高階函式「返回了乙個新的函式,該函式引用了外部作用域中的變數a,於是該函式稱為閉包函式。
閉包就是:引用了自由變數的函式。
自由變數:指在當前作用域引用但既沒有定義在當前作用域也未定義在全域性作用域,而是定義在外層的區域性作用域中的變數。
所以在此明確幾個關於閉包的要點:
閉包必然是定義在乙個函式內部的,因為區域性作用域只存於函式內。
區域性作用域的變數無法直接從外部訪問,只能通過作用域鏈訪問,所以閉包是訪問區域性變數的橋梁。
閉包造成的直接結果是自由變數不被垃圾**,所以自由變數可以快取一些資訊。
閉包的典型應用場景有兩個:
私有變數就是那些函式可以呼叫但是外部無法直接獲取的變數。
比如下面這個場景:
function user()
login()
};}const user = new (user())("diana", "password");
user.login();
我們希望隱藏使用者的密碼,只允許內部訪問,此時就可以使用自由變數作為「私有變數」,返回乙個閉包進行訪問。
區域性變數的外部不可訪問性是關鍵,本質上這一切都來自於js使用的詞法作用域模型,變數只能從內向外單向查詢。
柯里化是一種操作技巧,在程式設計中指的是:
將接受n個引數的單個函式轉換為接受單個引數的n個函式。
比如下面這個場景:
function info(country, province, city)
我們想要列印城市資訊,對於某個省的城市我們需要重複的輸入country,province這兩個字段,此時我們可以對該函式進行「柯里化」改造:
function info(country) ;
};}const province = info("中國")("浙江省");
province("杭州市");
province("溫州市");
我們將接受三個引數"country,province,city"的函式轉換為三個只接受單個引數的函式,然後根據需要隨時生成乙個已經內建」部分引數「的函式。
這麼做最大的好處是提高了**的復用性,我們可以提前快取一些引數,避免重複輸入。
偏函式也是一種操作技巧,在程式設計中指的是:
將接受n個引數的單個函式任意固定a個引數,返回接受剩餘n-a個引數的函式。
偏函式和柯里化屬於一類操作,區別在於:
柯里化強調函式只能接受「單引數」,有n個引數就要拆解為n個單引數函式;
偏函式更加「隨意」,將接受n個引數的函式一分為二,任意固定乙個或多個引數。
上面的例子如果使用偏函式:
function info(country) ;
}info("中國")("浙江省", "杭州市");
info("中國")("浙江省", "溫州市");
柯里化和偏函式本質沒什麼區別,只是約束不同。能夠實現這類操作的核心有兩點:
在於「自由變數」的不**性,由於垃圾**不去銷毀閉包中引用的自由變數,我們才能快取部分引數;
在於js使用靜態的詞法作用域,詞法作用域的劃分和查詢根據」**書寫「的位置來決定。
其實私有變數也用到了這兩個特性。
閉包與柯里化
一 柯里化的概念 在電腦科學中,柯里化是把接受多個引數的函式變換成接受乙個單一引數 最初函式的第乙個引數 的函式,並且返回接受餘下的引數且返回結果的新函式的技術。這個技術由christopher strachey以邏輯學家 haskell curry 命名的,儘管它是 moses schnfinke...
閉包的應用(私有變數 珂理化 偏函式)
const countmodule function function tozero return countmodule.addcount 1 countmodule.addcount 2 countmodule.addcount 3 countmodule.tozero 0 countmodul...
Scala的閉包和柯里化
1 scala中的閉包 閉包是指有權訪問另外乙個函式作用域中的變數的函式。可以理解為能夠讀取另乙個函式作用域的變數的函式。乙個函式的函式體是乙個新的函式,這個函式體函式是閉包 有權訪問另外乙個函式作用域中的變數 閉包可以作為函式引數傳遞 val filteralllogclasrdd casecla...