摘要:前面我們已經知道如何書寫函數式的程序了,但是我們還沒提到控制流異常處理異步操作和狀態呢容器容器為函數式編程里普通的變量對象函數提供了一層極其強大的外衣,賦予了它們一些很驚艷的特性按照我們的慣例,先從最簡單的容器入手。
如果你前面都看完了跟到了這里,我只能說你很棒棒,不過我不得不說,這才剛剛開始。前面我們已經知道如何書寫函數式的程序了,但是我們還沒提到控制流(control flow)、異常處理(error handling)、異步操作(asynchronous actions)和狀態(state)呢?
容器容器為函數式編程里普通的變量、對象、函數提供了一層極其強大的外衣,賦予了它們一些很驚艷的特性
按照我們的慣例,先從最簡單的容器入手。
var Container = function(x) { this.__value = x; } Container.of = function(x) { return new Container(x); };
試著執行以下Container.of(3),看看輸出的值。
jQuery $(...) 返回的對象并不是一個原生的 DOM 對象,而是對于原生對象的一種封裝,某種意義上就是一個“容器”。
我們接著添加一個map方法
Container.prototype.map = function(f){ return Container.of(f(this.__value)) } Container.of(3) .map(x => x + 1) //=> Container(4) .map(x => "Result is " + x); //=> Container("Result is 4")
這個跟前面我們提到的數組操作的map方法非常類似,數組的map方法返回一個新的數組,Container的map方法返回一個新的Container。
上面的這個具有map方法的容器就是我們接下來要引出來的函子。
Functor(函子)是實現了 map 并遵守一些特定規則的容器類型。
Functor 是一個對于函數調用的抽象,我們賦予容器自己去調用函數的能力。當 map 一個函數時,我們讓容器自己來運行這個函數,這樣容器就可以自由地選擇何時何地如何操作這個函數,以致于擁有惰性求值、錯誤處理、異步調用等等非常牛掰的特性
接著我們看看牛掰的Functor能為我們做什么
var Maybe = function(x) { this.__value = x; } Maybe.of = function(x) { return new Maybe(x); } Maybe.prototype.isNothing = function() { return (this.__value === null || this.__value === undefined); } Maybe.prototype.map = function(f) { return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value)); } Maybe.of("Malkovich Malkovich").map(match(/a/ig)); //=> Maybe(["a", "a"]) Maybe.of(null).map(match(/a/ig)); //=> Maybe(null),代碼并沒有報錯,我們在對函數調用時,檢查了函數是否為空
我們如果不想一值.map .map, 可以用柯里化函數對上面的代碼稍微改進一下
var map = curry((f, any_functor_at_all) => any_functor_at_all.map(f));
錯誤處理
var Left = function(x) { this.__value = x; } var Right = function(x) { this.__value = x; } Left.of = function(x) { return new Left(x); } Right.of = function(x) { return new Right(x); } Left.prototype.map = function(f) { return this; } Right.prototype.map = function(f) { return Right.of(f(this.__value)); }
var getAge = user => user.age ? Right.of(user.age) : Left.of("ERROR!"); getAge({name: "stark", age: "21"}).map(age => "Age is " + age); getAge({name: "stark"}).map(age => "Age is " + age); //Left 會終端機鏈式調用
最后來看下我們不得不做的IO操作
let readLocalStorage = () => { return window.localStorage; }
機智的改造成純函數
let readLocalStorage = () => { return () => {window.localStorage}; }
然而并沒有什么軟用
var IO = function(f) { this.__value = f; } IO.of = function(x) { return new IO(() => x); } IO.prototype.map = function(f) { return new IO(_.compose(f, this.__value)); }
var io_window = new IO(function(){ return window; }); io_window.map(function(win){ return win.innerWidth }); io_window.map(_.prop("location")).map(_.prop("href")).map(split("/")); var $ = function(selector) { return new IO(function(){ return document.querySelectorAll(selector); }); } $("#myDiv").map(head).map(function(div){ return div.innerHTML; });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82881.html
摘要:首先先祝大家國慶節快樂今天距離為我運營公眾號已經一個月了,今天把文章整合一下,希望對大家有幫助,也謝謝朋友的支持,我會繼續堅持原創,寫更好的文章給大家一視頻獲取學習資源分享合集二功能篇實現金額的語音播報功能基于模式風格的封裝之路炫酷動畫跳 showImg(https://segmentfault.com/img/remote/1460000011437678?w=900&h=500);...
摘要:首先先祝大家國慶節快樂今天距離為我運營公眾號已經一個月了,今天把文章整合一下,希望對大家有幫助,也謝謝朋友的支持,我會繼續堅持原創,寫更好的文章給大家一視頻獲取學習資源分享合集二功能篇實現金額的語音播報功能基于模式風格的封裝之路炫酷動畫跳 showImg(https://segmentfault.com/img/remote/1460000011437678?w=900&h=500);...
摘要:函數式編程我在網上看了很多關于的函數式編程的教程,不過我感覺很多不是照抄的或者就是故弄玄虛。函數式編程幾分鐘就完事兒了,簡單的讓人發指。函數式編程理解這么多就夠了,再實用就可以看源碼了。 JS函數式編程 我在網上看了很多關于javascript的函數式編程的教程,不過我感覺很多不是照抄的或者就是故弄玄虛。js發展到今天越來越往瑜伽圈的風氣發展了,拿腔拿調裝13不好好說話,好像你講的東...
閱讀 2130·2021-11-18 10:07
閱讀 3507·2021-09-04 16:48
閱讀 3214·2019-08-30 15:53
閱讀 1235·2019-08-30 12:55
閱讀 2453·2019-08-29 15:08
閱讀 3149·2019-08-29 15:04
閱讀 2879·2019-08-29 14:21
閱讀 2906·2019-08-29 11:21