0

私は次の方法を持っています:

DBConnection.prototype.successHandler = function(){
  console.log("DB_INFO: Schema created");
  for (k in this) console.log(k);
  this.setStatus(DB_STATUS_OK);
}

私はこれを次のようなトランザクションで呼び出します。

DBConnection.prototype.createSchema = function(){
  try {
    this.c2db.transaction(
      function(tx){
        tx.executeSql('CREATE TABLE IF NOT EXISTS person(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL DEFAULT "");',
        [], this.nullDataHandler, this.errorHandler);
        tx.executeSql("INSERT INTO person(id, name) VALUES (NULL, 'miloud');",
          [], this.nullDataHandler, this.errorHandler);
      },
      this.errorHandler,
      this.successHandler
    );
  } catch(e){
    console.log("DB_ERROR: error during insert with message: " + e);
    return;
  }
}

問題は、次のようになることです。Uncaught TypeError:Object [objectWindow]にはメソッド'setStatus' がありません。これは、アクセスしているものがDBConnection、成功コールバックにいるときに使用しているインスタンスではないことを明確に示しています。どうして?これは、このコールバック内で何を指しているのですか?この問題を克服する方法はありますか?

編集

コールバックは次のように定義されます。

DBConnection.prototype.errorHandler = function(errorMsg){
  console.log("DB_ERROR: error creating schema with msg " + errorMsg.message);
}
DBConnection.prototype.successHandler = function(){
  console.log("DB_INFO: Schema created");
  for (k in this) console.log(k);
  this.setStatus(DB_STATUS_OK);
}

そして、setStatusメソッドを

DBConnection.prototype.setStatus = function(str_status){
  localStorage.setItem(db_name, str_status);
}

ありがとう!

4

1 に答える 1

2

これはthis、javascript関数内で、呼び出されたときにドット表記でその前にあるオブジェクトを参照するために発生します。ただし、javascriptの関数はファーストクラスの値であり、オブジェクトの外部で(または実際にはまったく異なるオブジェクトに対して)呼び出すことができます。たとえば、objがオブジェクトの場合:

obj.myFunc = function() { console.log(this) };
obj.myFunc(); // <- Here this === obj
var freeFunc = obj.myFunc; // The function is just a value, we can pass it around
freeFunc(); // <- Now this === the top object (normally window)
            // Still the same function, but *how* it was called matters

あなたがしていることは、によって参照される関数を呼び出しに渡すことですthis.successHandlertransaction、関数はあなたがそれを取得したオブジェクトについて何も知りません。によって呼び出されるtransactionと、オブジェクトなしで実行され、 。thisになりwindowます。

これを解決するには、javascriptにクロージャがあるという事実を使用して、関数を別の無名関数でラップします。

DBConnection.prototype.createSchema = function(){
  try {

    var that = this;

    this.c2db.transaction(
      function(tx){
        tx.executeSql('CREATE TABLE IF NOT EXISTS person(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL DEFAULT "");',
        [], this.nullDataHandler, this.errorHandler);
        tx.executeSql("INSERT INTO person(id, name) VALUES (NULL, 'miloud');",
          [], this.nullDataHandler, this.errorHandler);
      },
      this.errorHandler,
      function() { that.successHandler(); }
    );
  } catch(e){
    console.log("DB_ERROR: error during insert with message: " + e);
    return;
  }
}

これで、元のと同じasで呼び出さsuccessHandlerれます。thatthisthis

これはよくある誤解ですthisが、オンラインでもたくさんの説明があります。グーグル「javascriptthis」だけです。

于 2012-07-13T15:42:06.793 に答える