javascript - Phonegap本地存储和面向对象的JS

标签 javascript html cordova sqlite local-storage

我有以下方法:

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 函数中的 this 引用了调用时以点表示法位于其前面的对象。但 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 将被调用,that 作为 this,与原来的 this 相同。

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

关于javascript - Phonegap本地存储和面向对象的JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11470167/

相关文章:

javascript - 在 click 方法外部触发 e.preventDefault()

javascript - dropzone.js:上传后显示复选标记和 x 图标

html - 带有 ngClass 的 Angular 2 枚举

android - 我需要学习 java 才能构建 Android 应用程序吗?

javascript - 使用纯 JS 单击时从 li 元素获取文本和 id

javascript - 地理位置 watchPosition 每秒触发一次

javascript - 通俗地说,Webpack 加载器

javascript - IE11全屏显示白屏

html - 相对位置并不总是在最前面

php - 使用 PHP 在 HTML 页面中显示 SQL 表内容