OOP:

* Flock.js

function Flock(n) {
  this.seagulls = n;
}

Flock.prototype.conjoin = function(other) {
  // console.log(this, 'conjoin', other);
  this.seagulls += other.seagulls;
  return this;
};

Flock.prototype.breed = function(other) {
  // console.log(this, 'breed', other);
  this.seagulls *= other.seagulls;
  return this;
};

module.exports = Flock;

* index.js

const Flock = require('./Flock');

let a = new Flock(4),
  b = new Flock(2),
  c = new Flock(0);

let result = a.conjoin(c).breed(b)
  .conjoin(a.breed(b)).seagulls;

console.log(result);

$ node index.js 
Flock { seagulls: 4 } 'conjoin' Flock { seagulls: 0 }
Flock { seagulls: 4 } 'breed' Flock { seagulls: 2 }
Flock { seagulls: 8 } 'breed' Flock { seagulls: 2 }
Flock { seagulls: 16 } 'conjoin' Flock { seagulls: 16 }
32
 

变量a不断发生变化,得到的结果不是期望的结果。

// a.conjoin(c).breed(b) => a = (4 + 0) * 2 = 8 (return a)
// a.breed(b) =>  a = 8 * 2 = 16
// a.conjoin(a) => 16 + 16 = 32

* functional.js

const conjoin = function(x, y) {
  return x + y;
};

const breed = function(x, y) {
  return x * y;
};

let a = 4, b = 2, c = 0;
let result = conjoin(
  breed(b, conjoin(a, c)),
  breed(a, b)
);
console.log(result); // 16

b* (a + c) + a*b = 2*a*b + b * c = 2*8+0 = 16

函数的定义:

一般地,在一个变化过程中,假设有2个变量x和y,如果对于任意一个x都有唯一一个确定的y与他对应,那么就称y是x的函数。

如果一个底层函数使用了this,而且是以函数的方式被调用的,那么就要非常小心了。

var fs = require('fs');
// ERROR: fs.readFile('xxx.txt', DB.save);
fs.readFile('xxx.txt', DB.save.bind(DB));

curry

函数的科里化:

科里化是指把接收多个参数的原函数变换成接收一个单一参数(第一个)的函数,然后返回接收剩余参数的新函数、

只向函数传递一部分参数来调用它,让它返回一个函数去处理剩下的参数。

 

函数组合

* compose.js

var compose = function(f, g) {
    return function(x) {
	return f(g(x));
    }
}

// var snakeCase = compose(replace(/\s+/ig, '_'), toLowerCase);
// ReferenceError: replace is not defined

var snakeCase = compose((x) => x.replace(/\s+/ig, '_'),
		        (x) => x.toLowerCase());
var s = "The world is a VAMPIRE";
console.log(snakeCase(s));
// the_world_is_a_vampire