需要一些帮助了解JS模块模式的基础知识

时间:2011-11-11 18:24:06

标签: javascript jquery module closures

我正在尝试使用显示模块模式来组织我的代码。 我有一个关于如何设置setter方法的基本问题。

$(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);
});

问题是我没有在控制台输出中获得someNewVal,而是获得了undefined!我有一种感觉,我在做一些非常愚蠢的事情。

4 个答案:

答案 0 :(得分:4)

您还可以通过了解所涉及的变量和函数的范围以另一种方式解决此问题。

当您退回对象构造{ curRow: curRow ... },这只是初始化命名的对象构件curRow在的范围的变量curRow的匿名函数;它不会在它们之间创建任何持久的连接。

在匿名函数返回时,调用designs.setCurRow在该范围内完全按照您的期望,但该变量现在是完全无法访问到外面的世界更新curRow变量 - 之间没有任何连接它和设计的curRow成员。

您可以通过setCurRow方法对this.curRow进行操作来解决此问题,就像在其他解决方案中一样。在这种情况下,您不需要在原始范围内使curRow变量,因为它完全未使用。另一个解决方案是为当前的方法添加“getter”方法:

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());

由于getCurRowsetCurRow功能了在含有变量的范围关闭varRow,他们可以达到回成范围和访问和改变只能在其中访问的变量。

在这种情况下,使curRow成为您返回的对象的成员可能更简单,但另一种方式也很有用,因为您可以使用它来有效地创建private members and methods

答案 1 :(得分:1)

看起来你想要一个对象,而不是一个模块:

$(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);
});

答案 2 :(得分:0)

问题是setCurRow在设置curRow之后设置变量designs.curRow的值。考虑这样的事情:

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

您的代码执行相同的操作,但使用对象属性和setter方法使其看起来很复杂。 : - )

答案 3 :(得分:0)

正如Ruakh指出的那样,你永远不会在返回的对象上重新分配curRow,因此它始终是默认值。将其更改为:

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

一切都应该有效*

*至少大多数情况下 - 您将无法在call上使用applysetCurRow(或将其传递给setTimeout或{{ 1}}不首先将它绑定到您的对象(setInterval),因为designs在JavaScript中的调用时被绑定。