简体   繁体   中英

Need some help understanding basics about JS module pattern

I am trying to organize my code using the revealing module pattern. I have a very basic question about how to set up a setter method.

$(document).ready(function() {  
    var designs = (function() {  
        var curRow,  
            setCurRow = function(val) {  
                curRow = val;  
            },
            initTable = function() {  
                setCurRow(0);
            };
        return {
            curRow : curRow,
            setCurRow : setCurRow,
            initTable : initTable
        }
    }) ();  
    designs.initTable();  
    designs.setCurRow(someNewVal);
    console.log(designs.curRow);
});

The problem is that i dont get the someNewVal in the console output, I get undefined instead! I have a feeling I am doing something pretty silly here.

You can also solve this in another way by understanding the scopes of the variables and functions involved.

When you return your object constructor { curRow: curRow ... } , that just initializes the object member named curRow to the value of the variable curRow in the scope of the anonymous function; it doesn't create any persistent connection between them.

Once the anonymous function returns, calling designs.setCurRow is updating the curRow variable in that scope exactly as you expect, but that variable is now totally inaccessible to the outside world -- there is no connection between it and the curRow member of designs.

You can solve this by making the setCurRow method operate on this.curRow , as in the other solutions. In that case you don't need to make curRow a variable in the original scope, since it's entirely unused. The other solution is to add a 'getter' method to your current one:

var designs = (function() {  
    var curRow,  
    setCurRow = function(val) {  
        curRow = val;  
    },
    getCurRow = function() {
        return curRow;
    },
    initTable = function() {  
        setCurRow(0);
    };
    return {
        getCurRow : getCurRow,
        setCurRow : setCurRow,
        initTable : initTable
    };
}) ();  
designs.initTable();  
designs.setCurRow(someNewVal);
console.log(designs.getCurRow());

Because getCurRow and setCurRow are functions that are closed in the scope containing the variable varRow , they can reach back into that scope and access and change variables that are only accessible within it.

In this case making curRow a member of the object you return is probably simpler, but the other way is useful too since you can use it to create effectively private members and methods .

Looks like you want an object, not a module:

$(document).ready(function() {  
    var designs = {
            setCurRow: function(val) {  
                this.curRow = val;  
            },
            initTable: function() {  
                this.setCurRow(0);
            },
            curRow: 0
    };  
    designs.initTable();  
    designs.setCurRow(someNewVal);
    console.log(designs.curRow);
});

The problem is that setCurRow sets the value of the variable curRow after designs.curRow has already been set. Consider something like this:

var a = 1;
b = a; // sets b = a = 1
b = 2; // sets b = 2; leaves a = 1

Your code is doing the same thing, but with object-properties and setter methods to make it look complicated. :-)

As ruakh pointed out, you never re-assign curRow on the returned object, so it is always the default value. Change it to:

setCurRow = function(val) {  
    this.curRow = curRow = val;  
},

And everything should work * .

* At least mostly - you won't be able to use call and apply on setCurRow (or pass it to setTimeout or setInterval without binding it first to your object ( designs ), since this is bound at call time in JavaScript.

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