小丸子函数式编程初探

小丸子函数式编程初探

1. question

这里写图片描述

前一个项目,顺利完成的时候感觉特别棒。但是后面需求方迭代加需求的时候,甚至代码重构的时候,感觉特别乏力。

当时说不出来问题在哪,但是感觉自己写的代码维护成本很高,加需求的时候需要四处去改。

考虑一下,大概有以下几个方面做的不够好:

  1. 组件设计

项目的复杂组件在所选的技术栈上并没有例子( nej + regular)。所以不得已,复杂组件都是自己手写定制的。项目周期又比较紧,以至于,有一两个组件,特别复杂,其实并没有封装的好,而且是同事在我的组件基础上继续改变成另一个组件。这个时候组件设计的问题就暴露出来了。很多逻辑并没有抽离好,当后面组件越来越庞大的时候,手忙脚乱。

有一句话说的很好,

数据结构设计的不合理,这个组件就已经失败了(原话我忘了,这是我翻译的,是这个意思。)

  1. 编程方式

最近尝试使用组内大佬(他是函数式编程小王子)编写的一堆高阶函数,用它们来简化一些常用函数和操作。感觉特别棒。

甚至震惊我的是:有一个页面,我预估一天可以写完,但是我尝试用大佬的高阶函数封装的一套数据与操作绑定的小框架(我词穷,就当小框架吧)来实现的时候,我一小时就把页面写完了,而且代码量很小很干净。

顿时感觉自己之前写的代码low爆了。

这里写图片描述

  1. 回调地狱

目前项目各种使用promise了。

有时间深入研究。


本文研究一下关于编程方式:函数式编程

下面带大家看看不同的编程方式,对于项目的开发及其维护,多么重要吧。

2. 函数式编程

1. 命令式编程 vs 函数式编程

先看一个例子吧。

<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <div id="switcher" class="on"></div>
    <script>
      const switcher = document.querySelector('#switcher');
      function changeColor(evt) {
        const target = evt.target;
        if (target.className === 'on') {
          target.className = 'off';
        } else {
          target.className = 'on';
        }
      }
      switcher.onclick = changeColor;
    </script>
    <style>
      #switcher {
        width: 100px;
        height: 100px;
        border: solid 1px white;
        border-radius: 50px;
      }
      .on {
        background-color: green;
      }
      .off {
        background-color: red;
      }
    </style>
  </body>
</html>

这段代码实现的效果是页面上有一盏红绿灯,每点击一次,就进行一次红/绿切换。

核心代码是这个函数。

function changeColor(evt) {
        const target = evt.target;
        if (target.className === 'on') {
          target.className = 'off';
        } else {
          target.className = 'on';
        }
      }

我上一个项目,大量充斥着这样的代码,if``else满天飞。

现在是红灯绿灯切换,如果加一个黄灯,又要加一堆if``else。是不是维护成本挺高的。

用函数式的思维来实现是这个样子的:

const switcher = document.querySelector('#switcher');

      function toggleQueue(...actions) {
        return (...args) => {
          const act = actions.shift();
          actions.push(act);
          return act.apply(this, args);
        }

      }
      switcher.onclick = toggleQueue(
        // evt => evt.target.className = 'yellow',
        evt => evt.target.className = 'off',
        evt => evt.target.className = 'on'

      );

需要黄灯只需要加一句evt => evt.target.className = 'yellow'就可以了。

2. 高阶函数

输入是函数或者输出是函数的函数。(这也是我翻译的,是这个意思)

3. 实用小栗子

本文几个函数式编程的小例子,都是项目中最常用的功能,希望给函数式编程小白一些启发。

// 函数节流
function throttle(fn, timer = 500) {
  let time;
  return (...args) => {
    if (!time) {
      fn.apply(this, args);
      time = setTimeout(() => {
        time = null;
      }, timer);
    }
  }
}

function call() {
  console.log('hello');
}

switcher.onclick = throttle(call);
// 只生效一次
function once(fn) {
  return (...args) => {
    if (fn) {
      fn.apply(this, args);
      fn = null;
    }
  }

}

function call() {
  console.log('hello');
}

switcher.onclick = once(call);
// 链式调用
function chain(fn) {
  return (...args) => {
    fn.apply(null, args);
      return this;
  }
}

function call() {
  console.log('hello');
}

function write() {
  console.log('write');
}
call = chain(call);
write = chain(write);
call().write();
// 批量处理
function pack(map) {
  return (obj) => {
    for(let key in obj) {
      map[key].call(this, obj[key]);
    }
  }
}

function call(name) {
  console.log('call ' + name);
}

function write(name) {
  console.log('write ' + name);
}
let css = pack({call: call, write: write})

css({call: 'hello', write: 'world'});

我的理解是,函数式的设计就是把一个个功能剥离出来,实现为高阶函数,给最基础的函数附加上一系列的功能。

这里写图片描述

参考:
http://www.zcfy.cc/article/javascript-and-functional-programming-an-introduction

http://www.zcfy.cc/article/imperative-vs-declarative

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值