0

何を達成したいですか?

Looperというクラスがあります。各オブジェクトに名前と独自のルーパーを付けたいと思います。

期待する結果

Created Looper Object...
one
Created Looper Object...
two
one - 1
two - 1
one - 2
two - 2
one - 3
two - 3
one - 4
two - 4
one - 5
two - 5
.......

私のコード

このコードで、私はそれが動作することを期待しています.. 

var Looper = (function (window, document, $) {

    this.i = 1;

    var Looper = function () {
        console.log('Created Looper Object...');
    }

    var getName = function () {
        return this.name;
    }

    var setName = function (newName) {
        this.name = newName;
    }

    var loop = function () {
        console.log(getName() + ' - ' + this.i);
        this.i = this.i + 1;
    }

    var startLoop = function () {
        window.setInterval(loop, 1000);
    }

    Looper.prototype = {
        getName: getName,
        setName: setName,
        start: startLoop
    }

    return Looper;
})(window, document, jQuery);

var one = new Looper();
one.setName('one');
console.log(one.getName());
one.start();

var two = new Looper();
two.setName('two');
console.log(two.getName());
two.start();

jsFiddle の例

私の結果

しかし、そうではありません.... 

Created Looper Object...
one
Created Looper Object...
two
result - 1
result - 2
result - 3
result - 4
result - 5
.......

誰かがなぜそうしないのか教えてもらえますか?

私の問題は、this.nameオブジェクトごとに設定できることです。

しかしthis.i、オブジェクトごとに設定することはできません。彼らはお互いを追い越しますi。静的のように見えthis.iますか?!?!?

また、使用するconsole.log(two.getName());と機能します。しかし、ループ内this.nameresult?

4

1 に答える 1

2

this.i = 1;コンストラクター関数内でプロパティを作成する必要があります。

var Looper = function () {
    this.i = 1;
    console.log('Created Looper Object...');
}

現在のコードでは、thisキーワードはグローバル オブジェクト ( window) を参照しているため、実際にはグローバル変数 (ある種の「静的」です) を作成しています。

setIntervalfromと呼ばれる関数でも同様のことが起こり、this再びグローバル オブジェクトに設定されます (これが、数値を検出する理由です)。インスタンスでメソッドを明示的に呼び出す必要があります。たとえば、loopLooper

var startLoop = function () {
    var that = this;
    window.setInterval(function() {
       loop.call(that); // "that" refers to the Looper object, while "this" does not
       // if "loop" were a method on the Looper, it's equivalent to
       // that.loop()
    }, 1000);
}

または経由bind

var startLoop = function () {
    window.setInterval(loop.bind(this), 1000);
}

また、関数内で現在の Looper オブジェクトのメソッドとしてloop呼び出す必要があります。getName

this.getName()

すべての関数/メソッドがオブジェクトの (継承された) プロパティでアクセスできるだけでなく、モジュール内のローカル変数としてもアクセスできることは、少し混乱しているようです。JavaScript にはクラスがなく、 Java のようには機能しないことに注意してthisください。変数とプロパティを常に明示的に区別する必要があります。モジュールは次のようになります。

var Looper = (function() {

    function Looper() {
        this.i = 1;
        this.name = null;
        console.log('Created Looper Object:', this);
    }

    Looper.prototype.getName = function() {
        return this.name;
    };
    Looper.prototype.setName = function(newName) {
        this.name = newName;
    };
    Looper.prototype.start = function() {
        var that = this;
        window.setInterval(function() {
            console.log(that.getName() + ' - ' + that.i);
            that.i++;
        }, 1000);
    };

    return Looper;
});
于 2013-04-11T14:49:48.967 に答える