25

私は、javascript でモジュール パターンを明らかにすることに頭を悩ませようとしています。次のコード スニペットについて、2 つの点で困惑しています。

        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. ここでコンソールに書き込まれる 3 つの値は 100、150、100 です。値を指定して「addPoints」を呼び出すと、totalPoints 変数が更新されないことがわかります。addPoints 関数の totalPointsの値を調べると、適切にインクリメントされています。どうしたの?

  2. コンソールを使用してwindow.addPointsまたはwindow.getPointsを調べると、グローバルスコープに追加された関数宣言の前に「var」を使用していないため、それがわかります。それは間違っていませんか?私が見ている例のほとんどは、これを行っているようです。

感謝して受け取ったポインタ。

4

2 に答える 2

33

ここで番号を渡しています:

return {
    points: totalPoints,
    addPoints: addPoints
};

このコードは、次のものと同じです。

return {
    points: 100,
    addPoints: addPoints
};

を渡しています。への参照でtotalPointsはありません (後者は JavaScript では使用できません)。したがって、totalPoints変更されても、オブジェクトの値は変更されません。


関数の使用

これを回避する最も簡単な方法は、関数を使用して最新の結果を取得することgetPointsです (既に取得しているように)。この JSFiddleは完全な例を示しています。

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

欠点は、呼び出し元がpoints関数呼び出しとして要求する必要があることです。

console.log(george.points());

ゲッターとセッターの使用

もう 1 つの解決策は、getter を使用することです。gettergeorge.totalPoints(まだ) 広くサポートされていませんが、だけで更新された値を取得できます。次のようなゲッターを実装できます。

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それが意味するものであれば、コンマを使用して 1 つのステートメントを作成できます。

var totalPoints = 100, // expands to three `var` statements, so no
    addPoints = ...,   // global variables
    getPoints = ...;
于 2012-01-17T10:44:18.193 に答える
0

これは、ゲッター/セッターを必要とせずtotalPoints、プロパティとして保持する、わずかに異なるソリューションです。

    var Child = function () {

        var _api;

        return _api = {

            addPoints: addPoints,
            points: 100
        };

        /* ----------- */

        function addPoints(points) {
            _api.points += points;
            return _api.points;
        };

    };
于 2015-03-20T12:31:35.230 に答える