首页 > 解决方案 > Javascript 对象样式模块到函数式编程

问题描述

我正在开发一个简单的 Javascript 模块,我想让它遵循函数式编程风格。

该模块基本上允许您测量开始和结束事件时已经过去了多少时间,并以 2 个测量值的块发送数据:

const register = {
  marks: {},
  marksCount: 0,

  restart: function () {
    this.marks = {}
    this.marksCount = 0
  },

  startMark: function (id) {
    performance.mark(`${id}/start`)
  },

  finishMark: function (id) {
    performance.mark(`${id}/end`)
    performance.measure(id, `${id}/start`, `${id}/end`)
    this.marksCount++
    this.marks[id] = performance.getEntriesByName(id, 'measure')[0]
    if (this.marksCount === 2) {
      console.log(this.marks)
      this.restart()
    }
  }
}


// then you can use it like this
register.startMark('event1')
register.startMark('event2')
register.finishMark('event1')
register.finishMark('event2')

我一直在阅读一些关于 FP 如何管理状态的帖子,我真的很想看看如何使用纯 FP 原理编写这个简单的模块,特别是我们如何防止改变属性。

标签: javascriptfunctional-programming

解决方案


使对象不可写入非常简单。例如。

const storage = v => () => v;
const test = storage(10); 
console.log(test()); // prints 10, but you have no way to change v

您的时间度量的功能版本可能如下所示:

const startMark = () => {
  const start = performance.now();
  return () => {
    const end = performance.now();
    return end - start;
  };
}

// How to use
const endMark1 = startMark();
const endMark2 = startMark();
const result1 = endMark1();
const result2 = endMark2();
console.log('time1', result1, 'time2', result2);

// do something else
const result11 = endMark1();
console.log('time1-2', result11);

由于它是功能性的,您可以endTimer多次使用它,它会返回从开始到现在的时间,即使在连续调用时也是如此。


推荐阅读