Zamieniamy funkcję konstruującą z lekcji o Maybe-Monad na literał obiektu. Poznajemy gettery i settery. Do dzieła.

Nasz Maybe-Monad:

function Selected(selector){
    this.el = document.querySelector(selector);
}

Selected.prototype.bind = function(transform){
    return this.el == null ? this : transform(this.el);
}

Ok, gettery i settery wyglądają tak:

function selectEl(selector){
    return {
        el: document.querySelector(selector),

        get textContent(){
            return this.el.textContent;
        },

        set textContent(val){
            this.el.textContent = val;
        }
    }    
}

Użycie:

window.addEventListener('DOMContentLoaded', function(){

    let para = selectEl("#para");

    console.log(para.textContent);

    para.textContent = "BLA BLA BLA";
    
});

Dodajemy zabezpieczenie przed nullem:

function selectEl(selector){
    return {
        el: document.querySelector(selector),

        get textContent(){
            if(this.el === null)
                return null;
            return this.el.textContent;
        },

        set textContent(val){
            if(this.el === null)
                return;
            this.el.textContent = val;
        }
    }    
}

Możemy to jednak rozwiązać inaczej dodając bind:

function selectEl(selector){
    return {
        el: document.querySelector(selector),

        get textContent(){
            return this.bind((el) => el.textContent);
        },

        set textContent(val){
            this.bind((el) => el.textContent = val);
        },

        bind(transform){
            return this.el == null ? this : transform(this.el);
        },

        valueOf(){
            return this.el;
        }
    }
    
}

Sami zdecydujmy, czy bind ma zwracać null czy this. Możemy jeszcze dodać funkcję retrySelect:

function selectEl(selector){
    return {
        el: document.querySelector(selector),

        get textContent(){
            return this.bind((el) => el.textContent);
        },

        set textContent(val){
            this.bind((el) => el.textContent = val);
        },

        bind(transform){
            return this.el == null ? this : transform(this.el);
        },

        valueOf(){
            return this.el;
        },

        retrySelect(selector){
            this.el ??= document.querySelector(selector);
        }
    }
    
}