2

わかりました。javaScript を使った最初のクラスを行うのはこれが初めてです。JQuery の使い方を何ヶ月も勉強してきたので、教えるのはそれほど難しくありません。このコードでは、多くの質問をします..

わかりました、これは私の最初のJavaScriptクラスのコードです

window.myclass = function(){
    this.n1 = 0;
    this.n2 = 0;
    this.ans = 0;
    this.hehe = 0;

    this.defaultNumbersAdd = function(){

       this.hehe =setInterval(function(){
          //just an example of inert function...
          //the truth is i can't grab the this.n1 and this.n2...
          this.ans = this.n1 + this.n2;
       },100);
       clearTimeout(this.hehe);
    };

    this.returnAns = function(){
       return this.ans;
    };

    this.getAnswer = function(){
        this.defaultNumbersAdd(); //i want to reuse this function but I can't access it
        return this.returnAns(); //and also this one
    };

    this.modifynumbers = function(n1,n2){
        this.n1 = n1;
        this.n2 = n2;
    };
};

var myclassins = new window.myclass();
alert(myclassins.getAnswer);

今私の質問は

1)関数内で使用するクラス変数(this.vars)を取得するにはどうすればよいですか

2)別の関数内で他の関数を使用するにはどうすればよいですか

注:私の説明があいまいでしたら申し訳ありません...

4

5 に答える 5

4

thiswindow.myclass オブジェクト内のポインターはそのオブジェクト自体を指し、それを使用して、n1 や n2 など、そのオブジェクトの本質的なプロパティを定義します。

ただし、オブジェクト内で定義された関数内からは、thisポインタはオブジェクトではなく関数を参照します。***ただし、setTimeouts および setIntervals 内では、「this」キーワードはウィンドウ オブジェクトまたはグローバル スコープを参照します。(たとえば、下部の更新を参照してください。)

したがって、クラスのインスタンス化に使用したグローバルスコープの変数の名前を使用して、プロパティに直接アクセスするだけです。

    this.returnAns = function(){
       return myclassins.ans;
    };

ただし、上記のメソッドは、インスタンス化時にオブジェクトに付けられた名前にクラスを関連付けるため、単一のオブジェクトに対してのみ有効です。

より良い解決策は、オブジェクト内で変数を定義し、それを使用して「this」ポインターを参照することです。

window.myclass = function(){
    this.n1 = 0;
    this.n2 = 0;
    this.ans = 0;
    this.hehe = 0;
    var _self = this;   // reference to "this"

    this.defaultNumbersAdd = function(){

       myclass.hehe =setInterval(function(){
          //just an example of inert function...
              //the truth is i can't grab the this.n1 and this.n2...
          _self.ans = _self.n1 + _self.n2;
          console.log(_self.ans);
       },100);
       clearTimeout(_self.hehe);
    };

    this.returnAns = function(){
       return _self.ans;
    };

    this.getAnswer = function(){
        this.defaultNumbersAdd(); //i want to reuse this function but I can't access it
        return _self.returnAns(); //and also this one
    };

    this.modifynumbers = function(n1,n2){
        _self.n1 = n1;
        _self.n2 = n2;
    };
};

最後に、クロージャーを使用して関数を定義し、別の関数を返す関数に "this" ポインターを渡すという別の手法もあります。次のようにします。

    this.modifynumbers = (function(__this) {
        return function(n1,n2){
            __this.n1 = n1;
            __this.n2 = n2;
        }
    })(this);

もちろん、最も簡単な方法はvar self;を使用することです。ただし、JavaScript では、タスクを達成するためのさまざまな方法がいくつかあり、これらの手法はさまざまなシナリオで役立ちます。

アップデート:

@apsillers は、setTimeout および setInterval 関数によって呼び出されるコールバック内で参照される場合、「this」キーワードがウィンドウ オブジェクトを指すことを指摘しました。次に例を示します。

// top level scope
var global = "globalvalue";

window.demo = function() {
    this.somevar = "somevalue";        

    this.someFunct = function() {
        console.info("somevar = " + this.somevar);  // prints "somevalue"
        console.info("global = " + this.global);   // prints undefined! this points to "demo"!

        setTimeout( function() {
            console.info("timeout - somevar = " + this.somevar);  // undefined! references the "window" context
            console.info("timeout - global = " + this.global);   // prints "globalvalue"
        },1000);
    };
};
var dem = new demo();

dem.somevar;   // accessible from outside the object. prints "somevalue"
dem.someFunct();

someFunct() の出力:

# inside method of object
somevar = somevalue
global = undefined

# inside timeout
timeout - somevar = undefined
timeout - global = globalvalue

ご覧のとおり、setTimeout 内では、「this」は明らかにウィンドウまたはグローバル スコープを指しています。(注: 実際には、その小さなコード スニペットを取得して、Chrome または Firebug デバッガーで実行できます。)

于 2012-05-23T03:34:44.207 に答える
3

この記事で説明されているモジュール パターンを使用できます。これを使用する利点は、プライベート変数を持ち、パブリックにしたいものだけを公開できることです。

var Myclass = (function(){

    var

    // Private
    n1 = 0,
    n2 = 0,
    ans = 0,
    hehe = 0,

    defaultNumbersAdd = function(){
       hehe = setInterval(function(){
          this.ans = this.n1 + this.n2;
       },100);
       clearTimeout(hehe);
    },

    returnAns = function(){
       return ans;
    },

    getAnswer = function(){
        this.defaultNumbersAdd();
        return returnAns()    
    },

    modifynumbers = function(n1 ,n2){
        n1 = n1;
        n2 = n2;
    };

    // Public
    return {
      defaultNumbersAdd: defaultNumbersAdd,
      getAnswer: getAnswer,
      modifynumbers: modifynumbers
    };
}());

// Then you can use the object as it already exists
myclass.method();
于 2012-05-23T03:33:06.903 に答える
2

「this」キーワードに混乱していると思います。

「this」は、現在のオブジェクト コンテキストを参照します。setInterval を使用すると、別のthis意味を持つ別のコンテキストに関数を渡します。したがってthis、現在参照されているオブジェクトを渡す変数に割り当てるか、内部defaultNumbers.addでプロパティを vars に割り当てることができます。

this.defaultNumbersAdd = function(){
   var ans = this.ans,
   n1 = this.n1,
   n2 = this.n2;

   this.hehe =setInterval(function(){
      //just an example of inert function...
      //the truth is i can't grab the this.n1 and this.n2...
      ans = n1 + n2;
   },100);
   clearTimeout(this.hehe);
};
于 2012-05-23T03:36:21.523 に答える
1

私は通常、これのために新しい変数を宣言します:

window.myclass = function(){
....
....

var self = this
....
....
}

これで自分自身を呼び出すことができます。..... あなたが望むものなら、なんでも

于 2012-05-23T03:25:17.890 に答える
1

ポイント #1 : オブジェクトからすべてのメンバー変数が必要な場合は、次を使用しますfor(.. in ..)

// output all keys and values
for(key in myclassins) {
    console.log(key, myclassins[key]);
}

関数は JavaScript のファーストクラスの変数であることに注意してください。そのため、関数以外のメンバー変数のみを列挙したい場合は、次のようmyclassinsにします。

// output all keys and values that are not functions
for(key in myclassins) {
    if(!myclassins[key] instanceof Function) {
        console.log(key, myclassins[key]);
    }
}

Point #2 : JavaScript では、this変数は関数のコンテキストと呼ばれます。コンテキストは変更される可能性がありますsetInterval。たとえば、 を呼び出すと、匿名関数がthis == window現在のオブジェクトのコンテキストではなく のコンテキストで実行されます。現在のオブジェクトのコンテキストを参照する場合は、コンストラクターの開始時に別の変数 ( など) に格納し、オブジェクトをvar self = this;参照するときselfに無名setInterval関数で参照します。

これが機能するのは、JavaScript がクロージャーをサポートしているためです。つまり、関数を定義すると、その新しい関数は現在のスコープに現在存在する (この場合) を含むすべての変数にアクセスできますself

:

  • JavaScript はクラスベースではなく、プロトタイプベースです。理解するのが難しい区別である可能性があり、正確なコードに関係するものではありません。ただし、「JavaScript クラス」と言うと、訂正する人がいる場合があります。

  • 型の名前を頭文字でキャメルケースにするのは伝統的です。たとえば、インスタンスfooBarは型FullTimeEmployee( fullTimeEmployeeorではありませんfulltimeemployee) です。

于 2012-05-23T03:28:15.220 に答える