国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript函數(shù)式編程之pointfree與聲明式編程

zorpan / 822人閱讀

摘要:函數(shù)式編程中的的意思就是無參或無值,是一種編程范式,也作,就是無參編程的意思了。的聲明式代碼是函數(shù)式編程應(yīng)該有的樣子。

函數(shù)式編程中的pointfree的意思就是“無參”或“無值”,pointfree style是一種編程范式,也作tacit programming,就是“無參編程”的意思了。什么是“無參編程”?

// 這就是有參的,因?yàn)橛衱ord
var snakeCase = word => word.toLowerCase().replace(/s+/ig, "_");

// 這是pointfree
var snakeCase = compose(replace(/s+/ig, "_"), toLowerCase);

從另一個(gè)角度看,有參的函數(shù)的目的是得到一個(gè)數(shù)據(jù),而pointfree的函數(shù)的目的是得到另一個(gè)函數(shù)。
所以,如下的方程,雖然也有參,也可以認(rèn)為是pointfree的。

const titlesForYear = year =>
  pipe(
    filter(publishedInYear(year)),
    map(book => book.title)
  )

那這pointfree有什么用?
它可以讓我們把注意力集中在函數(shù)上,參數(shù)命名的麻煩肯定是省了,代碼也更簡潔優(yōu)雅。
需要注意的是,一個(gè)pointfree的函數(shù)可能是由眾多非pointfree的函數(shù)組成的,也就是說底層的基礎(chǔ)函數(shù)大都是有參的,pointfree體現(xiàn)在用基礎(chǔ)函數(shù)組合而成的高級函數(shù)上。如果我們使用函數(shù)式編程的工具,如ramda,這些基礎(chǔ)函數(shù)大都已經(jīng)被寫好了,這樣我們?nèi)憄ointfree的代碼就很容易了。

什么是聲明式編程?它區(qū)別于命令式編程

// 命令式
var words = [];
for (i = 0; i < otherWords.length; i++) {
  words.push(otherWords[i].word);
}

// 聲明式
var words = otherWords.map(function(ele){ return ele.word; });

容易看出,命令式的代碼,我們不但要去遍歷,還要關(guān)注如何遍歷。而聲明式的就容易很多,可以節(jié)省我們的注意力,代碼也更加簡潔。

其他的命令式的寫法有:使用ifelse進(jìn)行的條件判斷,使用算數(shù)運(yùn)算符進(jìn)行的算數(shù)運(yùn)算,使用比較運(yùn)算符進(jìn)行的比較運(yùn)算和使用邏輯運(yùn)算符進(jìn)行的邏輯運(yùn)算。

至于那些說“雖然如此,但使用命令式循環(huán)速度要快很多”的人,我建議你們先去學(xué)學(xué) JIT 優(yōu)化代碼的相關(guān)知識。這里有一個(gè)非常棒的視頻,可能會對你有幫助。

需要注意的是,要實(shí)現(xiàn)這種聲明式的編程,首先我們要有這個(gè)map方法,這一點(diǎn)與pointfree相同,都是需要我們先對常用的操作做一次封裝,而這些常用的操作本身還是命令式的。

pointfree的聲明式代碼是函數(shù)式編程應(yīng)該有的樣子。

最后用一個(gè)來自Scott Sauyet的文章《Favoring Curry》中的例子,使用的函數(shù)式工具是ramda。下面的代碼不需要一句一句的看,大概體會一下就可以了。

一組JSON數(shù)據(jù)

var data = {
    result: "SUCCESS",
    interfaceVersion: "1.0.3",
    requested: "10/17/2013 15:31:20",
    lastUpdated: "10/16/2013 10:52:39",
    tasks: [
        {id: 104, complete: false,            priority: "high",
                  dueDate: "2013-11-29",      username: "Scott",
                  title: "Do something",      created: "9/22/2013"},
        {id: 105, complete: false,            priority: "medium",
                  dueDate: "2013-11-22",      username: "Lena",
                  title: "Do something else", created: "9/22/2013"},
        {id: 107, complete: true,             priority: "high",
                  dueDate: "2013-11-22",      username: "Mike",
                  title: "Fix the foo",       created: "9/22/2013"},
        {id: 108, complete: false,            priority: "low",
                  dueDate: "2013-11-15",      username: "Punam",
                  title: "Adjust the bar",    created: "9/25/2013"},
        {id: 110, complete: false,            priority: "medium",
                  dueDate: "2013-11-15",      username: "Scott",
                  title: "Rename everything", created: "10/2/2013"},
        {id: 112, complete: true,             priority: "high",
                  dueDate: "2013-11-27",      username: "Lena",
                  title: "Alter all quuxes",  created: "10/5/2013"}
        // , ...
    ]
};

需求是找到Scott所有未完成的任務(wù),并按照到期日期升序排列。

正確的結(jié)果是

[
    {id: 110, title: "Rename everything", 
        dueDate: "2013-11-15", priority: "medium"},
    {id: 104, title: "Do something", 
        dueDate: "2013-11-29", priority: "high"}
]

命令式的代碼如下

getIncompleteTaskSummaries = function(membername) {
    return fetchData()
        .then(function(data) {
            return data.tasks;
        })
        .then(function(tasks) {
            var results = [];
            for (var i = 0, len = tasks.length; i < len; i++) {
                if (tasks[i].username == membername) {
                    results.push(tasks[i]);
                }
            }
            return results;
        })
        .then(function(tasks) {
            var results = [];
            for (var i = 0, len = tasks.length; i < len; i++) {
                if (!tasks[i].complete) {
                    results.push(tasks[i]);
                }
            }
            return results;
        })
        .then(function(tasks) {
            var results = [], task;
            for (var i = 0, len = tasks.length; i < len; i++) {
                task = tasks[i];
                results.push({
                    id: task.id,
                    dueDate: task.dueDate,
                    title: task.title,
                    priority: task.priority
                })
            }
            return results;
        })
        .then(function(tasks) {
            tasks.sort(function(first, second) {
                var a = first.dueDate, b = second.dueDate;
                return a < b ? -1 : a > b ? 1 : 0;
            });
            return tasks;
        });
};

pointfree的代碼

var getIncompleteTaskSummaries = function(membername) {
  return fetchData()
    .then(R.prop("tasks"))
    .then(R.filter(R.propEq("username", membername)))
    .then(R.reject(R.propEq("complete", true)))
    .then(R.map(R.pick(["id", "dueDate", "title", "priority"])))
    .then(R.sortBy(R.prop("dueDate")));
};

pointfree的聲明式的代碼

// 提取 tasks 屬性
var SelectTasks = R.prop("tasks");

// 過濾出指定的用戶
var filterMember = member => R.filter(
  R.propEq("username", member)
);

// 排除已經(jīng)完成的任務(wù)
var excludeCompletedTasks = R.reject(R.propEq("complete", true));

// 選取指定屬性
var selectFields = R.map(
  R.pick(["id", "dueDate", "title", "priority"])
);

// 按照到期日期排序
var sortByDueDate = R.sortBy(R.prop("dueDate"));

// 合成函數(shù)
var getIncompleteTaskSummaries = function(membername) {
  return fetchData().then(
    R.pipe(
      SelectTasks,
      filterMember(membername),
      excludeCompletedTasks,
      selectFields,
      sortByDueDate,
    )
  );
};

參考文章

Pointfree編程風(fēng)格指南

Favoring Curry

JS函數(shù)式編程指南

Tacit programming

Thinking in Ramda: Pointfree Style

Thinking in Ramda: Declarative Programming

我在github https://github.com/zhuanyongx...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/94592.html

相關(guān)文章

  • JavaScript函數(shù)編程,真香組合(一)

    摘要:組合的概念是非常直觀的,并不是函數(shù)式編程獨(dú)有的,在我們生活中或者前端開發(fā)中處處可見。其實(shí)我們函數(shù)式編程里面的組合也是類似,函數(shù)組合就是一種將已被分解的簡單任務(wù)組織成復(fù)雜的整體過程。在函數(shù)式編程的世界中,有這樣一種很流行的編程風(fēng)格。 JavaScript函數(shù)式編程,真香之認(rèn)識函數(shù)式編程(一) 該系列文章不是針對前端新手,需要有一定的編程經(jīng)驗(yàn),而且了解 JavaScript 里面作用域,閉...

    mengbo 評論0 收藏0
  • JavaScript 函數(shù)編程(二)

    摘要:注意是單一參數(shù)柯里化是由以邏輯學(xué)家命名的,當(dāng)然編程語言也是源自他的名字,雖然柯里化是由和發(fā)明的。辨別類型和它們的含義是一項(xiàng)重要的技能,這項(xiàng)技能可以讓你在函數(shù)式編程的路上走得更遠(yuǎn)。 slide 地址 三、可以,這很函數(shù)式~ showImg(https://segmentfault.com/img/remote/1460000015978685?w=187&h=160); 3.1.函數(shù)是一...

    thursday 評論0 收藏0
  • Js-函數(shù)編程

    摘要:組合組合的功能非常強(qiáng)大,也是函數(shù)式編程的一個(gè)核心概念,所謂的對過程進(jìn)行封裝很大程度上就是依賴于組合。在理解之前,先認(rèn)識一個(gè)東西概念容器容器為函數(shù)式編程里普通的變量對象函數(shù)提供了一層極其強(qiáng)大的外衣,賦予了它們一些很驚艷的特性。 前言 JavaScript是一門多范式語言,即可使用OOP(面向?qū)ο螅部梢允褂肍P(函數(shù)式),由于筆者最近在學(xué)習(xí)React相關(guān)的技術(shù)棧,想進(jìn)一步深入了解其思想...

    whinc 評論0 收藏0
  • 前端_JavaScript

    摘要:為此決定自研一個(gè)富文本編輯器。例如當(dāng)要轉(zhuǎn)化的對象有環(huán)存在時(shí)子節(jié)點(diǎn)屬性賦值了父節(jié)點(diǎn)的引用,為了關(guān)于函數(shù)式編程的思考作者李英杰,美團(tuán)金融前端團(tuán)隊(duì)成員。只有正確使用作用域,才能使用優(yōu)秀的設(shè)計(jì)模式,幫助你規(guī)避副作用。 JavaScript 專題之惰性函數(shù) JavaScript 專題系列第十五篇,講解惰性函數(shù) 需求 我們現(xiàn)在需要寫一個(gè) foo 函數(shù),這個(gè)函數(shù)返回首次調(diào)用時(shí)的 Date 對象,注意...

    Benedict Evans 評論0 收藏0
  • JS每日一題:函數(shù)編程中代碼組合(compose)如何理解?

    摘要:期函數(shù)式編程中代碼組合如何理解定義顧名思義,在函數(shù)式編程中,就是將幾個(gè)有特點(diǎn)的函數(shù)拼湊在一起,讓它們結(jié)合,產(chǎn)生一個(gè)嶄新的函數(shù)代碼理解一個(gè)將小寫轉(zhuǎn)大寫的函數(shù)一個(gè)在字符后加的函數(shù)將兩個(gè)函數(shù)組合起來這里假設(shè)我們實(shí)現(xiàn)了每日一題每日一題顯示結(jié)果里上面 20190315期 函數(shù)式編程中代碼組合(compose)如何理解? 定義: 顧名思義,在函數(shù)式編程中,Compose就是將幾個(gè)有特點(diǎn)的函數(shù)拼湊在...

    Kaede 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<