Search code examples
javascriptoopprototypal-inheritance

Method chaining in es5 classes


CurrentUser = function (){}
CurrentUser.prototype = {
    record: undefined
}
CurrentUser.prototype.is = {
    get _parent() {return CurrentUser.prototype},

    get signedIn() {
        return !!this._parent.record
    }
}
User = new CurrentUser
User.record = {name:'Joe'}
User.is.signedIn //false

What I'm trying to do here is create a new User, give him some data (record) and based on that determine that he is signedIn (if his record has data - he is signedIn).

But what happens in reality is that User.is.signedIn getter is accessing CurrentUser.prototype instead of accessing User instance. And as CurrentUser.prototype.record is undefined - User.is.signedIn returns false.


Solution

  • I ended up doing this (saw Bergi's answer after I've found a solution)

    CurrentUser.prototype = {
        record: undefined,
        get is() { return {
            _parent: this,
            get signedIn() {return !!this._parent.record}
        }}
    }
    
    User = new CurrentUser
    User.record = {name:'Joe'}
    User.is.signedIn //true
    

    We make is getter return an object that holds a reference to CurrentUser.prototype via assigning this to _parent. And this object in turn has its own getters that when accessing _parent gain access to CurrentUser.prototype. Voila!
    Btw, if you have many other methods\getters inside the is getter - you can refactor it out into a standalone object and then add it to CurrentUser.prototype via Object.defineProperty().

    PS
    Many advised against chaining class methods but nobody could say why.
    I like my code to be as close to human language as possible - and User.is.signedIn just looks better to me than User.isSignedIn; I also put many other is-related checks inside the is method - so they don't clutter up User namespace.