Javascript模块模式、公共属性

Javascript模块模式、公共属性,javascript,jquery,design-patterns,module-pattern,Javascript,Jquery,Design Patterns,Module Pattern,我正试图了解javascript中的模块模式。下面的代码片段有两件事让我感到困惑 var Child = function () { var totalPoints = 100; addPoints = function (points) { totalPoints += points; return totalPoints; };

我正试图了解javascript中的模块模式。下面的代码片段有两件事让我感到困惑

        var Child = function () {
            var totalPoints = 100;
            addPoints = function (points) {
                totalPoints += points;
                return totalPoints;
            };
            getPoints = function () {
                return totalPoints;
            };
            return {
                points: totalPoints,
                addPoints: addPoints
            };
        };
        $(function () {
            var george = Child();
            console.log(george.points);
            console.log(george.addPoints(50));
            console.log(george.points);
        });
  • 这里写入控制台的三个值是100、150、100。这告诉我,当我用一个值调用“addPoints”时,totalPoints变量不会更新。如果我在addPoints函数中检查totalPoints的值,它已正确递增发生了什么事?

  • 如果我使用控制台检查window.addPoints或window.getPoints,我可以看到这一点,因为我没有在函数声明前面使用“var”,它们已经被添加到全局范围这是不是错了?我看到的大多数示例似乎都是这样的


  • 感谢您的指点。

    您在这里传递了一个数字:

    return {
        points: totalPoints,
        addPoints: addPoints
    };
    
    这段代码与以下代码没有区别:

    return {
        points: 100,
        addPoints: addPoints
    };
    
    您正在传递值;不是对
    totalPoints
    的引用(后者在JavaScript中是不可能的)。因此,当
    totalPoints
    更改时,对象中的值不会更改


    使用函数 解决这个问题的最简单方法是使用函数来获取最新的结果(如
    getPoints
    )。给出了一个完整的示例:

    return {
        points: function(x) { return totalPoints; }, // always up-to-date
        addPoints: addPoints
    };
    
    缺点是调用者现在必须要求
    作为函数调用:

    console.log(george.points());
    

    使用getter和setter 另一种解决方案是使用getter,它可以让您只需使用
    george.totalPoints
    即可获得更新的值,尽管getter还没有得到广泛的支持。您可以实现如下getter:

    var obj = {};
    
    obj.points = addPoints;
    
    // add a "special" property to the object instead of normal notation
    Object.defineProperty(obj, "totalPoints", {
        get: function() { // function that's executed when you use `.totalPoints`
            return totalPoints;
        }
    });
    
    return obj;
    

    其次,删除
    var
    会使函数全局化,这是正确的,但不可取。您可以使用逗号制作一个
    var
    语句,如果这是您的意思:

    var totalPoints = 100, // expands to three `var` statements, so no
        addPoints = ...,   // global variables
        getPoints = ...;
    

    这是一个稍有不同的解决方案,它不需要getter/setter,并将
    totalPoints
    保留为一个属性

        var Child = function () {
    
            var _api;
    
            return _api = {
    
                addPoints: addPoints,
                points: 100
            };
    
            /* ----------- */
    
            function addPoints(points) {
                _api.points += points;
                return _api.points;
            };
    
        };
    

    非常感谢,这真的很有帮助!非常感谢。这是非常有帮助的,所以我发了一篇关于它的帖子,需要二传手和获得者。希望它能帮助一些人。+1在过去的45分钟里,发现一个与此相关的bug让我抓狂!它提供了一个“getter-like”字段,但不是setter-它仍然是一个函数。