Takeshi Tokugawa YD
Takeshi Tokugawa YD

Reputation: 923

ES6: How to store the object inside this class?

The TopPage_R class is in certain degree the analogue of R class in the Android SDK (if don't go into details, the R class stores the references to images, string values etc). In my inherited ES6-class, CSS_CLASSE_SELECTORS is the static property (actually the method) that returns the css class selector (e. g. .header) by class name (e. g. header).

class R {

    static getSelectorsOfCssClasses(CssClassesObj){

        let OutputCssClassesObj = CssClassesObj;

        for (let key in OutputCssClassesObj){
            OutputCssClassesObj[key] = '.' + CssClassesObj[key];
        }

        return OutputCssClassesObj;
    }
}

class TopPage_R extends R {

    /* required even if constructor in the superclass nas not beed defined */
    constructor() {
        super();
    } 

    static get CSS_CLASSES () { return {
        header: 'header',
        logo: 'logo',
        navmenu: 'navmenu',
        footer: 'footer'
    }}

    static get CSS_CLASS_SELECTORS(){ 
        return R.getSelectorsOfCssClasses(TopPage_R.CSS_CLASSES)}
    }
}

Every time we call CSS_CLASS_SELECTORS method, new object will be created and the looping will be executed. What the waste of system resources, in't it?

console.log(TopPage_R.CSS_CLASS_SELECTORS.header);
// The new OutputCssClassesObj will be created again
console.log(TopPage_R.CSS_CLASS_SELECTORS.footer);

I need the CSS_CLASS_SELECTORS stored inside the inherited class. However I don't want to create the instance of the TopPage_R: I want to call this class and then it's static property as in Android SDK like setToolbarTitle(getString(R.string.app_name));

let pageResources = new TopPage_R(); // I don't want to create the instance >_<
let $header = jQuery(pageResources.CSS_CLASS_SELECTORS.footer);

Can I store the CSS_CLASS_SELECTORS inside the TopPage_R without creating of it's instance? Assume that CSS_CLASS property does not change during web app session.

Upvotes: 0

Views: 1982

Answers (2)

smnh
smnh

Reputation: 1745

Currently, ES6 does not support static properties, only static methods. But you can use old syntax to set static properties on a class:

class TopPage_R extends R {

    ...

    static get CSS_CLASS_SELECTORS() {
        return R.getSelectorsOfCssClasses(TopPage_R.CSS_CLASSES);
    }
}

TopPage_R.CSS_CLASSES = {
    header: 'header',
    logo: 'logo',
    navmenu: 'navmenu',
    footer: 'footer'
};

Another option, will be to define your css classes as a variable outside of the class. If you are using ES6 modules, then this variable will be hidden from the rest of your app, so no worries about privacy.

let CSS_CLASSES = {
    header: 'header',
    logo: 'logo',
    navmenu: 'navmenu',
    footer: 'footer'
};

class TopPage_R extends R {

    static get CSS_CLASSES () {
        return CSS_CLASSES;
    }

    static get CSS_CLASS_SELECTORS() {
        return R.getSelectorsOfCssClasses(TopPage_R.CSS_CLASSES);
    }
}

Or you can use Babel with Class properties transform to compile you code and then use:

class TopPage_R extends R {

    static CSS_CLASSES = {
        header: 'header',
        logo: 'logo',
        navmenu: 'navmenu',
        footer: 'footer'
    };

    static get CSS_CLASS_SELECTORS() {
        return R.getSelectorsOfCssClasses(TopPage_R.CSS_CLASSES);
    }
}

Upvotes: 1

Ben
Ben

Reputation: 5626

I don't know how this works with it being static specifically, but if you want to make a method available to a Class or Object without it running on every new instance you need to add it to the prototype.

R.prototype.getSelectorsOfCssClasses = function(CssClassesObj) {
  ...
}

See this question for more explanation: https://stackoverflow.com/a/5837860/1763258

Consider a classroom full of students. Putting something on the prototype is like putting something on the white board for them all to see.

Upvotes: 0

Related Questions