摘要:是函數柯里化的函數。例子柯里化有個常見作用參數復用構建高階函數延遲計算。是的,它其實就是柯里化的具體應用構建高階函數。這個是我認為的中最有意思的方法。不過要注意最后的。這同樣是用來組合高階函數的一個方法。
最近在學習JS函數式編程相關的內容,于是詳細的翻看了Lodash的文檔,感到別有洞天。這里把自己對一些API的使用和看法做個筆記記錄下。
Array _.head/_.last例子:
_.head([1, 2, 3]); // → 1 _.last([1, 2, 3]); // → 3
分別可以抽取數組第一個元素的值和最后一個元素的值。咋看之下覺得很無聊。但是跟下面兩個結合起來就厲害。
_.tail/_.initial例子:
_.tail([1, 2, 3]); // → [2, 3] _.initial([1, 2, 3]); // → [1, 2]
也如字面描述一般容易理解的函數。但是結合上面的兩個函數就產生很大能量。
首先看一個針對數組尾部特殊化處理的例子:
let names=["fred", "barney", "pebbles"]; _.initial(names).join(", ") + (_.size(names) > 1 ? ", & " : "") + _.last(names); // → "fred, barney, & pebbles"
怎么樣比簡單的寫for+if else優雅很多吧。接著我們來看看遞歸求和:
function sum(arr){ return _.head(arr) ? ( _.head(arr) + sum( _.tail(arr) ) ) : 0; }
Tips
1)其實好像數組都可以表現為
[a, [b, [c .....]]]
然后再將其扁平化的結果。 是不是?所以結合這四個函數,很多數組遍歷的操作都可以改寫成遞歸的方式。雖然性能可能略差,但是可讀性反而更強了(并非所有的遞歸都一定損耗性能,詳細可以去了解下JIT優化)。
2)但是在ES6中,更推薦優先使用數組的解構。
_.zip例子:
_.zip(["fred", "barney"], [30, 40]); // → [["fred", 30], ["barney", 40]]
_.zip(*array) 將幾個數組按照位置組成新的數組,返回數組列表。這個方法就有點像SQL里面select兩個列的情況。對重組數據結構非常有幫助。
_.unzip既然lodash是個函數庫,那有zip肯定也有他的逆運算unzip。這里就不舉例了。unzip其實可以看作對ES6數組解構的補充,應用的場景也是十分相似的。
Collection _.map/_.reduce/_.filter這三個函數其實早就名聲在外,就不舉例了。列出來只是為了提醒,遍歷集合可不僅僅只有_.each。任何時候都優先考慮這些函數。
_.every/_.some例子:
let users = [ { "user": "barney", "active": true }, { "user": "fred", "active": false } ]; _.every(users, { "user": "barney", "active": false }); // → false _.some(users, ["active", false]); // → true
什么?看不懂?
_.every => && _.some => ||
懂了吧。其實同樣也算是對_.each的擴充。還有他們都有條件短路的優化哦。
Function _.curry是函數柯里化的函數。不要問我為什么不是庫里化。什么是柯里化自行百度。
例子:
let abc = function(a, b, c) { return [a, b, c]; }; let curried = _.curry(abc); curried(1)(2)(3); // → [1, 2, 3] curried(1, 2)(3); // → [1, 2, 3] curried(1, 2, 3); // → [1, 2, 3] // Curried with placeholders. curried(1)(_, 3)(2); // → [1, 2, 3]
柯里化有3個常見作用:1. 參數復用;2. 構建高階函數;3. 延遲計算。
參數復用的例子:
let parse = function(data, config){ …… return ……; }; let config = {}; let parseByConfig = _.curryRight(parse)(config);
如代碼所示,這是一個數據解析函數,通過某些配置按照一定的規則去解析數據。如果在某個場景下參數配置都一樣。那可以用柯里化先引入一個參數。然后再接收不同的數據。這樣就不用在每次調用時都引入同樣的config參數。
剩下兩個特性一個等會講,一個不在本文討論范圍內。
_.partial部分函數,我習慣這么叫他,還是先看例子。
let greet = function(greeting, name) { return greeting + " " + name; }; let sayHelloTo = _.partial(greet, "hello"); sayHelloTo("fred"); // → "hello fred" // Partially applied with placeholders. let greetFred = _.partial(greet, _, "fred"); greetFred("hi"); // → "hi fred" let greet = function(greeting, name) { return greeting + " " + name; }; let sayHelloTo = _.partial(greet, "hello"); sayHelloTo("fred"); // → "hello fred" // Partially applied with placeholders. let greetFred = _.partial(greet, _, "fred"); greetFred("hi"); // → "hi fred"
好像跟柯里化很像。是的,它其實就是柯里化的具體應用——構建高階函數。_.curry會把一個函數轉化成可以柯里化函數,而當這個柯里化函數接受了一定的參數后,它就變成了一個部分應用函數了。
Seq _.chain這個是我認為的lodash中最有意思的方法。
$("div").css("color","red") .on("click", function(){}) .fadeIn();
作為一個合格的前端攻城獅,你對這個一定不陌生。它一定給你帶來過很多美好的記憶。那我們如何讓這樣一段優雅的代碼應用到非DOM對象上呢。用_.chain就行了。
_.head( _.map( _.sortBy("users", "age"), function(o) { return `${o.user} is ${o.age}`; } ) ) _.chain(users) .sortBy("age") .map(function(o) { return o.user + " is " + o.age; }) .head() .value();
兩段代碼在做一樣的事情。你更喜歡哪個呢。不過要注意_.chain最后的value。因為_.chain用一個容器包裝了你的對象,最后需要通過value返回出真正的值。如果不能理解,聯想一下下面這段代碼:
$("div")[0].classList
用jQuery選擇器篩選到的是jQuery對象,而如果要調用真正的DOM對象的屬性的話,還要用索引去調用它。
Util _.flowfunction square(n) { return n * n; } var addSquare = _.flow(_.add, square); addSquare(1, 2); // → 9
這同樣是用來組合高階函數的一個方法。如果用數學的角度去思考的話,就有點像, 把函數 f(), g(), 和h() 組合起來可以得到復合函數 f( g( h() ) )。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79387.html
摘要:例如現在的入門學習手記系列。收到粉絲留言和打賞的喜悅。安裝上一篇入門學習手記一,主要是介紹了的核心概念,是整個學習過程的基礎知識。新生成的類似如下入門學習手記因為生成的內容過多,我直接省略掉了。 showImg(https://segmentfault.com/img/bVbk5Nd?w=1150&h=599); 本人微信公眾號:前端修煉之路,歡迎關注。 最近開始想要維護一個個人的公眾...
摘要:中文文檔目前我只找到了版本,現在已經更新到了,好多文檔已經過期。而且中太多,有時候常用的幾個我總是記不住名字,在這里貼出來,方便自己和大家。原生用法直接使用的根據條件去除某個元素。 lodash中文文檔目前我只找到了3.10.x版本,現在lodash已經更新到4.17.x了,好多文檔已經過期。而且lodash中api太多,有時候常用的幾個我總是記不住名字,在這里貼出來,方便自己和大家。...
摘要:文檔地址中文文檔英文文檔源碼地址第一個函數是,不過源碼中依賴了,所以第一篇文章就從開始。這個函數的作用就是裁剪數組,從下標開始,到下標結束,但是并不包含,并將結果作為一個數組返回。并且注明了這個方法用于代替來確保數組正確返回。 百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。 文檔地址:中文文檔?? 英文文檔源...
摘要:文檔地址中文文檔英文文檔源碼地址將數組拆分成多個長度的區塊,并將這些區塊組成一個新數組。如果無法被分割成全部等長的區塊,那么最后剩余的元素將組成一個區塊。 百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。 文檔地址:中文文檔?? 英文文檔源碼地址:gayhub _.chunk(array, [size...
摘要:文檔地址中文文檔英文文檔源碼地址創建一個新數組,包含原數組中所有的非假值元素。例如和都是被認為是假值。下面對比一下兩者效率,如下圖傳送門可以看到使用更快,如果沒有兼容性需求,還是使用原生函數比較好。 百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。 文檔地址:中文文檔?? 英文文檔源碼地址:gayhub ...
閱讀 733·2021-11-23 09:51
閱讀 2430·2021-10-11 11:10
閱讀 1299·2021-09-23 11:21
閱讀 1091·2021-09-10 10:50
閱讀 882·2019-08-30 15:54
閱讀 3326·2019-08-30 15:53
閱讀 3287·2019-08-30 15:53
閱讀 3186·2019-08-29 17:23