Odtwarzamy pojęcie compose znane z programowania w paradygmacie funkcyjnym w programowaniu obiektowym w JavaScript.

Na początek przypomnienie compose:

const addTwo = (num) => num + 2;

const mulByTwo = (num) => num * 2;

const compose = (...fns) => (data) => fns.reduceRight((acc, fun) => fun(acc), data);

const composed = compose(
    addTwo,
    mulByTwo
);

let num = 2;
let composedResult = composed(num);

console.log(composedResult);
//6

Idzie od dołu. Czyli – funkcja dodana jako pierwsza zostaje ostatnia. Najpierw mnoży, potem dodaje w tym przykładzie. Czyli:

class Compose {
    #data = null;
    #functions = [];

    setData(data) {
        this.#data = data;
        return this;
    }

    composeFunc(func){
        this.#functions.push(func);
        return this;
    }

    //(...)
}

Taki zapis sprawi, że pierwsza dodana funkcja będzie ostatnią, którą zrzucimy popując. Wystarczy dodać funkcję start:


class Compose {
    #data = null;
    #functions = [];

    //(...)

    start(){

        if(!this.#data)
            throw new Error("Data empty!");

        while(this.#functions.length){
            let currFunc = this.#functions.pop();
            this.#data = currFunc(this.#data);
        }

        let result = this.#data;
        this.#data = null;
        return result;
    }
}

Teraz testujemy:

const addTwo = (num) => num + 2;

const mulByTwo = (num) => num * 2;

const compose = (...fns) => (data) => fns.reduceRight((acc, fun) => fun(acc), data);

const composed = compose(
    addTwo,
    mulByTwo
);

let num = 2;
let composedResult = composed(num);

console.log(composedResult);
//6

let composeObj = new Compose();

let composedRes2 = composeObj
.setData(num)
.composeFunc(addTwo)
.composeFunc(mulByTwo)
.start();

console.log(composedRes2);
//6

Działa.