JS函数式编程读书笔记 - 1

本文章纪录本人在进修 函数式 中明白到的一些东西,加深影象和而且整顿纪录下来,轻易以后的温习。

在近期看到了《JavaScript函数式编程》这本书预售的时刻就定了下来。重要目标是个人如今照样不明白什么是函数式编程。在本身进修的历程当中一向听到身旁的人说面向历程编程和面向对象编程,而函数式就异常少。为了本身不要落后于其他同砚的脚步,故想以写笔记的体式格局去分享和纪录本身浏览中所吸取的学问。

js 和函数式编程

书中用了一句简朴的话来回复了什么是函数式编程:

函数式编程经由过程运用函数来将值转换为笼统单元,接着用于构建软件体系。

我以为一定有同砚看了这一句照样不怎么动什么是函数式编程,且为什么要运用函数式编程。背面的很多例子都运用到了Underscore

以函数为笼统单元

笼统要领是指隐藏了细节的函数。举一个书中的例子,一个检测输出岁数值的函数(重假如关于毛病和正告的报告):

function parseAge(age) {
    if (!_.isString(age))
        throw new Error("Expecting a string");
    var a;
    console.log("Attempting to parse an age");

    a = parseInt(age, 10);
    if (_.isNaN(a)) {
        console.log(["Could not parse age: "].join());
        a = 0;
    }

    return a;
}

上面的函数推断我们是不是是输入一个岁数,且必需是字符串情势。接着就是来运转这个函数:

parseAge("42"); //=> 42
parseAge(42); //=> Error:Expecting a string
parseAge("hhhh"); //=> 0

上面的parseAge函数事情一般没有什么问题。假如我们要修正输出毛病=信息和正告的显现体式格局、那末就须要修正响应的代码行,以及其他处所的输出形式。书中给的要领是经由过程将它们笼统成差别的函数来完成:

function fail(thing) {
    throw new Error(thing);
}

function warn(thing) {
    console.log(["WARNING:", thing].join(''));
}

function note(thing) {
    console.log(["NOTE:", thing].join(''));
}

接着就是运用上面的函数,去重构parseAge这个函数。

funciton parseAge(age) {
    if (!_.isString(age))
        fail("Expecting a string");
    var a;

    note("Attempting to parse an age");
    a = parseInt(age, 10);

    if (_.isNaN(a)) {
        warn(["Could not parse age:", age].join(""));
        a = 0;
    }

    return a;
}

把报告毛病的代码都放到差别的函数里去,且重构后的parseAge和之前的也没有多大的变化。然则差别的就是如今报告毛病、信息和正告的主意已被笼统化。毛病、信息和正告的报告结果也是完整被修正了。

这么做是,由于行动包含在单一的函数中,所以函数可以被可以供应相似行动的新函数庖代,或直接被完整差别的行动庖代。

封装和隐藏

这个题目很轻易明白,举个例子。像我们常常运用iife来防止全局的污染,这就是一个封装和隐藏的很好例子。经由过程运用iife来隐藏本身的写的一些变量和要领,目标就是不去污染全局的环境。这也是运用闭包的体式格局来隐藏数据。

由于闭包也是一种函数。且和如今在进修函数式编程有莫大的关联。然则也不要忘记了之前进修的面向对象式封装,毕竟这两者不能说谁越发的好。然则都控制了也不是一件什么坏事。一句老话:看需求。

以函数为行动单元

隐藏数据和行动(一般不轻易于疾速修正)只是一种讲函数作为笼统单元的体式格局。另一种体式格局就是供应一种简朴地存储体式格局和通报基本行动的离线散单元。

书中一个小栗子,经由过程运用js语法来索引数组中的一个值:

var arr = ['a', 'b', 'c'];
arr[1] //=> b

虽然上面索引数组中的中的一个值很简朴,但并没有方法可以在不把它放到函数里的前提下,猎取这个行动并根据须要来运用他/她。写一个简朴函数nth,用来索引数组中的一个值:

function nth(a, index) {
    return a[index];
}

接着运转:

nth(arr, 1); //=> b

运转胜利,然则假如传入一个空对象时,就会报错了。因而,假如想缭绕nth来完成函数笼统,我们或许会设想下面的声明:nth返回一个存储在许可索引接见的数据范例中的有效袁术。这段声明的关键在于索引数据的范例的观点。或许须要一个函数来推断范例:

function isIndexed(data) {
    return _.isArray(data) || _.isString(data);
}

接着继承完美nth函数。isIndexed函数是一个供应了推断某个数据是不是为字符串或许数组的笼统。

function nth(a, index) {
    if (!_.isNumber(index)) 
        fail("Expected a number as the index");
    if (!isIndexed(a))
        fail("Not supported on non-indexed type");
    if ((index < 0) || (index > a.length - 1))
        fail("Index value is out of bounds");

    return a[index];
}

index抽对象构建nth函数笼统的体式格局一样,也可以以一样的体式格局来构建一个second笼统:

function second(a) {
    return nth(a, 1);
}

函数second许可在一个差别但相干的情况下,准确的运用nth函数:

second(arr); //=> b

经由过程上面的栗子,就晓得。我们可以把每一步都笼统成一个函数,把每个参数都笼统出来。虽然如许写觉得定义了很多函数。不过如许越发轻易明白每一项的功用和流程。

数据笼统

JavaScript 的对象原型模子是一个雄厚且基本的数据计划。

由于js没有类的缘由,就有了很多模仿类的要领,且在ES6上也涌现了class关键字。只管类有很多优点,但很多的时刻js应用程序的数据需求币类中的简朴的要多。

基于类的对象体系的一个有理的论据是完成用户界面的汗青运用。

js中的对象和数组已可以满足我们对数据的操作了,且Underscore也是重点也是怎样处置惩罚数组和对象。

实行和运用的浅易性是运用js的中间数据结构举行数据建模的目标。这并不是说面向对象或许基于类的要领就完整没有效。处置惩罚集合为中间的函数式体式格局越发合适处置惩罚与人有关的数据,而面向对象的要领最合适模仿人。

js函数式初试

在最先函数式编程前,须要先定义两个经常使用且有效的函数:

function existy(x) {
    return x != null
}

function truthy(x) {
    return (x !== false) && existy(x);
}
  • existy函数旨在定义事物之前的存在。js中就有两个值可以示意不存在:nullundefined
  • truthy函数用来推断一个对象是不是应当认为是true的同义词。

    我们可以在很多处所运用到这两个函数,实在函数式理念来自于它们的运用。有些同砚能够已熟习了很多js完成中的map forEach等要领。且Underscroe也供应了很多相似的要领,这或许就是挑选Underscroe来辅佐进修函数式编程的缘由。

    简朴说下就是:

  • 一个对”存在“的笼统函数的定义。
  • 一个建立在存在函数之上的,对”真“的笼统函数定义。
  • 经由过程其他函数来运用上面的两个函数,以完成更多的行动。

加快

也许了解了函数式编程以后。你能够会想这函数式编程不是很慢吗?比方前面猎取数组索引,有必要定义一个函数来特地猎取吗?直接用arr[index]绝对照那些函数来的快。

var arr = [1, 2, 3, 4, 5];

// 最快
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

// 较慢
_.each(arr, function (val, index) {
    console.log(index);
});

然则我们在写代码的时刻能够不会斟酌的那末深,或许运用函数确实比原生要慢一些。然则大多数情况下也不会去在意那末点时候,且如今有壮大的v8引擎,大部分情况下的他都能很高效的编译和实行我们的js代码。所以我们没有必要在还没有写出准确的代码前斟酌运算速率。

假如是我来挑选的话,能够会越发关注与代码的作风。那种写法写的惬意看的惬意就运用哪种,固然也是要保证基本的运算速率下,以不至于慢的离谱。看的惬意的代码比跑的快的代码能够越发有成就感。

总结

看完了第一章也是可以小结一下js的函数式编程。下面援用书上的总结:

  • 肯定笼统,并为其构建函数。
  • 应用已有的函数来构建越发庞杂的笼统。
  • 经由过程将现有的函数传给其他的函数来构建越发庞杂的笼统。

单是构建笼统照样不够的,假如可以把壮大的数据笼统连系来完成函数式编程结果会越发好。

    原文作者:_我已经从中二毕业了
    原文地址: https://segmentfault.com/a/1190000003056490
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞