15

JavaScript をかなりよく理解し始めたと思っていましたが、明らかにそうではありませんでした。私の問題を例で説明しましょう。まず、次のモジュールを定義します。

var Test = function() {
    var counter = 0;

    function init() {
        alert(counter);
    }

    return {
        counter: counter,
        init: init
    }
};

次に、2 つのインスタンスを作成します。

var test1 = new Test();
var test2 = new Test();

ここで、カウンター変数を (公開されているため) 更新し、いくつかのアラートを実行します。ここまでは順調ですね。

alert(test1.counter); // Alerts 0
test1.counter = 5;
alert(test2.counter); // Alerts 0
test2.counter = 10;
alert(test1.counter); // Alerts 5

では、最後に次のように言います。

test1.init(); // Alerts 0
test2.init(); // Alerts 0

これは私が理解していないビットです。このアラートが 0 になるのはなぜですか? 最初のアラートは 5 で、2 番目のアラートは 10 だと思っていました。

誰かが上記がどのように機能するかを説明したり、正しい方向に向けたりしていただければ幸いです。ありがとう

4

5 に答える 5

13

0内部の変数を変更していないため、関数によって返さTestれるオブジェクトを変更しているため、そのままです。counter「プライベート」に保たれ、関数のみTestがアクセスできます。

var Test = function() {
    var counter= 0;

    function init() {
            alert(counter);
    }
    function changeNum(n){
        counter = n;            //add a function inside `Test` so that it can
    }                           //access the variable

    return {
        counter: counter,
        init: init,
        changeNum: changeNum
    }
};

これで動作します: http://jsfiddle.net/DerekL/pP284/

var test1 = new Test();
alert(test1.counter);           //0
test1.init();                   //0
test1.changeNum(5);
alert(test1.counter);           //5
test1.init();                   //5

詳細については、JavaScript クロージャを参照してください。

于 2013-02-09T22:22:37.040 に答える
5

これが起こったことです:

  1. init() 関数は、counter変数への参照を保持する Test スコープ内で定義された変数をクロージャーにしました。
  2. counterTest() 関数からの戻り値により、別の variableが internal の値に設定された新しいオブジェクトが作成されましたcounter
  3. countertest1.counter = X を設定して 'another' を更新しますが、init() はまだ元の変数への参照を保持しています。

そのため、古い値が表示されます。

于 2013-02-09T22:28:56.040 に答える
3

投稿に間違いがあるかどうかはわかりませんが、上記のコードを次のように書き換えることができます。

var Test = function() {
  this.counter = 0;
}

Test.prototype.init = function() {
  alert(this.counter);  
}

var test1 = new Test();
var test2 = new Test();


test1.counter = 5;
test2.counter = 10;

test1.init(); // alerts 5

test2.init(); // alerts 10

あなたの例では、カウンターを Test オブジェクト/関数のプロパティに設定していません。呼び出すときtest1.counterに、以前は存在しなかった新しいプロパティを本質的に設定しており、init 関数はそのプロパティを参照していません。

デレクの回答が示すように、私の回答と彼の回答の 2 つの異なるパターンを少し混同しているようです。

于 2013-02-09T22:21:36.380 に答える
1
alert(test1.counter); // Alerts 0 ????? It's "0" because you call it before change counter to 5
test1.counter = 5;
alert(test2.counter); // Alerts 0 ????? It's "0" because you call it before change counter to 10
test2.counter = 10;
alert(test1.counter); // Alerts 5 | It's 5 because you call it AFTER change counter to 5
于 2020-03-05T14:48:15.563 に答える