Functional-Light-JS 摘录笔记(1)

function foo(...args) {
    console.log( args[3] );
}

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

foo( ...arr );                        // 4

Think of ... in this symmetric sense: in a value-list position, it spreads. In an assignment position -- like a parameter list, because arguments get assigned to parameters -- it gathers.

...在函数定义的时候作为数组聚合,作为变量使用的时候将分散。

Whichever behavior you invoke, ... makes working with arrays of arguments much easier. Gone are the days of slice(..)concat(..) and apply(..) to wrangle our argument value arrays.

用了这种新技巧后,不再需要时候slice/concat 去处理变量数组了。

But now we start to uncover the first bits of a principle that we'll come back to many more times in this text: declarative code often communicates more cleanly than imperative code.

声明式代码比指令式代码更清晰

Declarative code, like destructuring in the earlier snippet, focuses on what the outcome of a piece of code should be. Imperative code, like the manual assignments just shown, focuses more on how to get the outcome. If you later read the code, you have to mentally execute it to understand the desired outcome. The outcome is coded there, but it's not as clear.

声明式代码关注代码的结果,指令式代码关注结果的实现,阅读指令式代码的时候,还要在脑海中运行一下,蛋疼。

 

解构对象参数

function foo( {x,y} = {} ) {
    console.log( x, y );
}

foo( {
    y: 3
} );    

这种写法的好处在于,不必在意参数的顺序了,如果按以前的常见写法十分蛋疼:

function foo(x,y,z){
    
}

foo(null,null,1);//即使只想要参数z,前面参数仍需要占个坑

  In FP, we'll want our functions to be unary whenever possible, and sometimes we'll even use a variety of functional tricks to transform a function of higher arity to a unary form.

   函数式编程中,总是希望函数尽可能是一元的。

   另外,根据参数类型不同,在函数里做不同处理,虽然方便,但是从长远来看,会有麻烦。

   FP 精神之一,函数永远有显式返回值 ,而且通常不是undefined

除了在参数上面解构,还可以在表达式中解构数组或对象值。

function foo() {
    var retValue1 = 11;
    var retValue2 = 31;
    return [ retValue1, retValue2 ];
}

var [ x, y ] = foo();
console.log( x + y ); //42       

Early Return

作者提到一个例子,在逻辑判断中,return语句要尽可能考虑延后或者只有一个return语句。比如避免下面这种写法,

function foo(x) {
    if (x > 10) return x + 1;

    var y = x / 2;

    if (y > 3) {
        if (x % 2 == 0) return x;
    }

    if (y > 1) return y;

    return x;
}

写代码的时候还有一种常见的情况,即函数隐式地对全局参数做处理,并没有返回值。

var y;

function foo(x) {
    y = (2 * Math.pow( x, 2 )) + 3;
}

foo( 2 );

y;                        // 11

那么它和下面这种写法,有什么区别呢?

function foo(x) {
    return (2 * Math.pow( x, 2 )) + 3;
}

var y = foo( 2 );

y;    

首先,用返回值的方式赋值说明这是显式的,前者隐式。developers prefer explicit patterns over implicit ones.

另外一个更隐晦的例子:

function sum(list) {
    var total = 0;
    for (let i = 0; i < list.length; i++) {
        if (!list[i]) list[i] = 0;

        total = total + list[i];
    }

    return total;
}

var nums = [ 1, 3, 9, 27, , 84 ];

sum( nums );            // 124

显然,返回值是124,这没有什么问题,但是外部变量 nums呢? 在控制台输出的时候会发现nums数组变成了

[ 1, 3, 9, 27, 0, 84 ]

 外部变量被隐式改变了!! 这涉及到 Javascript 引用的问题:JS uses references and reference-copies for arrays, objects, and functions

参考 http://www.cnblogs.com/linhp/p/6085826.html

这种问题在函数式编程的世界里有一个专有名词:side effects,而一个没有副作用的函数则是纯函数。如果可能,纯函数最高 = =。

 

高阶函数的定义:

Functions can receive and return values of any type. A function that receives or returns one or more other function values has the special name: higher-order function.

This technique of specifying inputs in successive function calls is very common in FP, and comes in two forms: partial application and currying. We'll dive into them more thoroughly later in the text.

也就是说,下面这种函数体内的函数使用了输入值的形式在函数式编程中很常见。

function makeAdder(x) {
    return function sum(y){
        return x + y;
    };
}

What I'm getting at is there's multiple reasons why named functions are always more preferable to anonymous functions.As a matter of fact, I'd go so far as to say that there's basically never a case where an anonymous function is more preferable. They just don't really have any advantage over their named counterparts.

 基本上,匿名函数没什么好处,尽量避免。

Name every single function. And if you sit there stumped, unable to come up with a good name for some function you've written, I'd strongly suggest you don't fully understand that function's purpose yet -- or it's just too broad or abstract. You need to go back and re-design the function until this is more clear. And by that point, a name will become more apparent.

方法名称如果想不出好的,说明这个函数方法多少都有点问题,需要重新设计。

From my perspective, the problem is not with using objects to organize behavior. It's that we're trying to use implicit input instead of being explicit about it. When I'm wearing my FP hat, I want to leave this stuff on the shelf.

函数式编程 say no to this.

 

posted @ 2017-09-25 21:07  lymne  阅读(410)  评论(0编辑  收藏  举报