简体   繁体   中英

JS Revealing Module Pattern - access private variables via public methods

i created txtModule module using Revealing Module Pattern with jquery,

i want print value of a input tag to a console.. for that exposed test method as public as shown below code

        var txtModule = (function(window,$){

            var txt = {
                topics:{},
                test:function(){
                    console.log(this.input.val());    
                },
                _init:function(){
                    this._cacheDom();                        
                },
                _cacheDom:function(){  
                    this.input = $("input#c_input");                                     
                },
            }
            
            txt._init();
            
            return {                
                test : txt.test,
            }
        });
    
          
        var v = txtModule(window,$);
        v.test();

when execute test public method when try to access this.input variable there is a error appear as below

Uncaught TypeError: Cannot read properties of undefined (reading 'val')

I want to know how can correctly expose test method to outside to access this.input

Calling txt._init() populates the txt object with an input property - but then when you do

v.test();

later, you can see that the left side of the . is v - which is the object returned at the end

        return {                
            test : txt.test,
        }

and not the txt object. When you do v.test() , the this that the test function sees is the object that only has the test property.

It depends on whether you want the input to be visible externally or not - if not, then refer to txt , otherwise create a variable for the returned object and refer to it.

var txtModule = (function(window,$){
    var txt = {
        topics:{},
        test:function(){
            console.log(this.input.val());    
        },
        _init:function(){
            this._cacheDom();                        
        },
        _cacheDom:function(){  
            returnedObj.input = $("input#c_input");                                     
        },
    }

    const returnedObj = {                
        test : txt.test,
    };
    txt._init();
    return returnedObj;
});

var v = txtModule(window,$);
v.test();

But this is somewhat convoluted - having two different objects that collect somewhat similar key-value pairs makes things confusing. Consider if using only a single one instead would help, eg:

const txtModule = (function (window, $) {
    const input = $("input#c_input");
    const test = () => {
        console.log(input.val());
    };
    return { test };
});

const v = txtModule(window, $);
v.test();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM