【问题标题】:Phonegap localstorage and object-oriented JSPhonegap 本地存储和面向对象的 JS
【发布时间】:2012-07-13 06:51:00
【问题描述】:

我有以下方法:

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 [object Window] has no method 'setStatus' 这清楚地表明我正在访问的不是 DBConnection 实例当我在成功回调中时使用。怎么会? this 在回调中指的是什么?有没有办法克服这个问题?

编辑

回调定义为:

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);
}

谢谢!

【问题讨论】:

    标签: javascript html cordova sqlite local-storage


    【解决方案1】:

    这是因为 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.successHandler 引用的函数传递给transaction 调用,但该函数对您从中获取它的对象一无所知。当它被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;
      }
    }
    

    现在successHandler 将调用thatthis,与原来的this 相同。

    这是对this 的常见误解,但网上也有很多解释,只要谷歌“javascript this”即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多