0

インスタンス化できるクラスが必要で、プライベートおよびパブリック変数/メソッドを保持します。

ここで、プロトタイプの実装が正しいことを確認したいだけです。

前: (jsFiddle: http://jsfiddle.net/7UqSv/1/ )

var MyObject = (function ()
{        
    var oid = "'oid123'";
    var x = 1; 
    var y = 1;          
    incrementx = function()
    {        
         x = x +1;
         console.log('value of x: ' + x);
    }
    incrementxagain = function()
    {        
         x = x +1;
         console.log('value of x: ' + x);
    }
    return {
        oid : oid,
        incrementx: function (){ incrementx(); },
        incrementxagain: function (){ incrementxagain(); }      
    }
});

var NewMyObject = new MyObject();
NewMyObject.incrementx(); //outputs "value of x: 2"
NewMyObject.incrementxagain(); //outputs "value of x: 3"
console.log('oid ' + NewMyObject.oid); //outputs "oid 'oid123'"

後: (jsFiddle: http://jsfiddle.net/7UqSv/6/ )

var MyObject = (function ()
{        
    var oid = "'oid123'";
    this.x = 1; 
    var y = 1;    
    //*** ADDED REFERENCE TO THIS USING $this
    var $this = this;
    //*** MOVED 'incrementx' FUNCTION TO PROTOTYPE BELOW
    incrementxagain = function()
    {        
         $this.x = $this.x +1;
         console.log('value of x: ' + $this.x);
    }
    return {
        oid : oid,
        incrementx: function (){ $this.incrementx(); },
        incrementxagain: function (){ incrementxagain(); }      
    }
});

 //****** ADDED PROTOTYPE METHOD
MyObject.prototype.incrementx = function() { 
    this.x = this.x + 1; 
    console.log('value of x:' + this.x);
}

var NewMyObject = new MyObject();
NewMyObject.incrementx(); //outputs "value of x: 2"
NewMyObject.incrementxagain(); //outputs "value of x: 3"
console.log('oid ' + NewMyObject.oid); //outputs "oid 'oid123'"

どちらも機能しますが、変数で var を this に変更し、オブジェクトの作成時に $this に this への参照を格納する必要があるのは奇妙だと思いましたか? また、私のコードには多くの変数があるため、「これ」への追加の参照が必要になったため、より多くのコードを書かなければならないということですか? すなわち:

これ:

結果 = (x + y + z) * (x + y + z);

になります:

this.result = (this.x + this.y + this.z) * (this.x + this.y + this.z);

私がここでやっていることはアニットパターンか何かではないというサニティチェックですか?

ありがとう

4

1 に答える 1

0

いくつかのコメント:

  • はい、残念ながら、thisメンバー アクセスが使用されるすべての場所で必要です。
  • self一般的なパターンは、 (または_selfetc)という名前の変数を使用してthis参照を保持することです。$thisjQuery(または他のライブラリ)が関与していることを意味する可能性があるため、使用は避けます。もちろん、これは私のコーディング規約の好みです。コードベースで一貫している限り、あなたのやり方でそれを行うことは何も悪いことではありません。
  • 参照の保存は、次のようなクロージャー (コールバックなど) からのthis参照に使用されます。this

    var MyObject = function() {
        var self = this;
        jQuery(something).on("click", function() {
            // `this` here is NOT what you expect; it is set by jQuery to be
            // the DOM element in this case; to refer to the object, use `self`
            // as defined above:
            self.clicked();
        });
    };
    
  • コンストラクタ関数を括弧で囲む必要はありません: var MyObj = (function()...);var MyObj = function()...;

  • コンストラクター関数から何かを返すと、それは構築されたオブジェクトになります。だからthis != returnedValue!!! これにより、コードに微妙なバグが発生する可能性があることに注意してください!!!! したがって、何かを返す代わりに、何かを追加するだけですthis(後で例を示します)。
  • ちなみに、incrementxagainはvar として定義されていないので、グローバル スコープになっています!!! 別の微妙なバグ!!!
  • 名前MyObjectは少しわかりにくいです。MyObjectオブジェクトインスタンスではなく、コンストラクター関数 (従来の OO 用語のクラス) を保持します。したがって、私はむしろそれに名前を付けたいと思いますMyClass(そしてそれを として使用しますvar myObject = new MyClass())。繰り返しますが、これは多かれ少なかれ好みです。

あなたのものに大まかに基づいた私の提案/例:

var MyClass = function(element) {
    // public fields
    this.oid = "'oid123'";
    this.x = 1;
    // private field
    var y = 1;
    // `element`, the argument, is another private field preserved in this closure

    var self = this;

    jQuery(element).on("click", function() {
        self.clicked();
    });

    // public accessor of private field
    this.getY = function() {
        // no this or self; the `y` variable of the closure is accessed
        return y;
    };

    // public method accessing private state
    this.incrementxagain = function() {
        // no inner closure, use `this` directly
        this.x = this.x + y;
    }
    // don't return anything; `this` is set correctly
});

// public methods
MyClass.prototype.incrementx = function() { 
    this.x = this.x + 1;
};

MyClass.prototype.clicked = function() {
    ...
};

var element = document.getElementById("foo");
var myObject = new MyClass(element);

myObject次のプロパティが追加されました。

  • イド
  • バツ

およびメソッド:

  • インクリメントx()
  • クリックされた()
  • getY()
  • インクリメントxアゲイン()

Functionインスタンスごとにオブジェクトを作成しないように、プライベート疑似メソッドを作成するために使用するパターン:

var MyClass = (function() {
    function privatePseudoMethod1(x) {
        // `this` is passed as argument
        x.doStuff();
    }

    function privatePseudoMethod2() {
        // `this` is what you expect, but the call is more verbose
        this.doStuff();
    }

    // CONSTRUCTOR (to be returned after the prototype is set
    function MyClass(element) {
        ...
    }

    MyClass.prototype.xxx = function() {
        // two ways of calling private pseudo-methods
        privatePseudoMethod1(this);
        privatePseudoMethod1.call(this);
    };

    MyClass.prototype.doStuff = function() {
        ...
    };

    return MyClass; // <--- this becomes the constructor
})(); // <--- NOTE: the outer function is executed just once
于 2013-10-29T14:08:40.340 に答える