Javascript 揭示模块模式、公共(public)属性

标签 javascript jquery design-patterns module-pattern

我正在尝试了解 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);
        });
  1. 此处写入控制台的三个值是 100、150、100。这告诉我,当我使用某个值调用“addPoints”时,totalPoints 变量不会更新。如果我检查 addPoints 函数内的 TotalPoints 值,它已正确增加。 发生什么事了?

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

非常感谢您的指点。

最佳答案

您在此处传递一个数字:

return {
    points: totalPoints,
    addPoints: addPoints
};

这段代码与:

return {
    points: 100,
    addPoints: addPoints
};

您正在传递;不是对 totalPoints 的引用(后者在 JavaScript 中是不可能的)。因此,当 totalPoints 发生变化时,对象中的值不会发生变化。

<小时/>

使用函数

解决此问题的最简单方法是使用函数来获取最新结果(例如您已有的 getPoints)。 This JSFiddle给出一个完整的例子:

return {
    points: function(x) { return totalPoints; }, // always up-to-date
    addPoints: addPoints
};

缺点是调用者现在必须以函数调用的形式请求:

console.log(george.points());
<小时/>

使用 getter 和 setter

另一个解决方案是使用getters,它使您能够仅使用george.totalPoints获得更新的值,尽管getters没有得到广泛支持(然而)。您可以像这样实现 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 = ...;

关于Javascript 揭示模块模式、公共(public)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8893099/

相关文章:

javascript - 如何手动将值(并触发选择事件)设置为 jQuery 自动完成

java - Thymeleaf 到 madal jquery

c# - 这是在我的 MVC 3 ModelBinder 中适当使用服务定位器模式吗?

c# - DDD 中的创建日期和创建者放在哪里?

c++ - 我如何拆除多线程 C++ 中的观察者关系?

Javascript - 删除 map 中最旧的元素(对象)

javascript - 如何从数组 1 中删除项目并将项目推送到数组 2

javascript - 缩短 Ajax 代码

javascript - 一个简单的系列带来奇怪和意想不到的结果

javascript - 单击动画多个 jquery ui 对话框