我认为这个问题超出了典型的变量作用域和闭包范畴,或者说我很蠢。无论如何,以下是我的问题...
我正在一个jQuery插件中动态创建一堆对象。这些对象看起来像这样:
function WedgePath(canvas){
this.targetCanvas = canvas;
this.label;
this.logLabel = function(){ console.log(this.label) }
}
jQuery插件大致如下:
(function($) {
$.fn.myPlugin = function() {
return $(this).each(function() {
// Create Wedge Objects
for(var i = 1; i <= 30; i++){
var newWedge = new WedgePath(canvas);
newWedge.label = "my_wedge_"+i;
globalFunction(i, newWedge]);
}
});
}
})(jQuery);
所以...插件创建了许多wedgeObjects,然后为每个对象调用“globalFunction”,并传入最新的WedgePath实例。全局函数如下。
function globalFunction(indicator_id, pWedge){
var targetWedge = pWedge;
targetWedge.logLabel();
}
接下来发生的是控制台正确记录了每个楔形图的标签。然而,我需要在globalFunction中添加更多复杂性。实际上应该像这样...
function globalFunction(indicator_id, pWedge){
var targetWedge = pWedge;
someSql = "SELECT * FROM myTable WHERE id = ?";
dbInterface.executeSql(someSql, [indicator_id], function(transaction, result){
targetWedge.logLabel();
})
}
这里涉及到很多内容,我会解释一下。我正在使用客户端数据库存储(我称之为WebSQL)。'dbInterface'是我创建的一个简单Javascript对象的实例,它处理与客户端数据库交互的基础知识[在此问题的末尾显示]。executeSql方法最多可以采用4个参数。
- SQL字符串
- 一个可选的参数数组
- 一个可选的成功处理程序
- 一个可选的错误处理程序(在此示例中未使用)
我需要发生的是:当WebSQL查询完成后,它需要获取一些数据并操作特定楔子的某些属性。但是,当我在onSuccess处理程序内调用WedgePath的一个实例上的'logLabel'时,我得到的是创建于插件代码中的最后一个WedgePath实例的标签。
现在我怀疑问题出在var newWedge = new WedgePath(canvas)
行上。所以我尝试将每个newWedge推入一个数组中,我认为这样可以防止该行在每次迭代时替换或覆盖WedgePath实例...
wedgeArray = [];
// Inside the plugin...
for(var i = 1; i <= 30; i++){
var newWedge = new WedgePath(canvas);
newWedge.label = "my_wedge_"+i;
wedgeArray.push(newWedge);
}
for(var i = 0; i < wedgeArray.length; i++){
wedgeArray[i].logLabel()
}
但是,我得到的是WedgePath的最后一个实例被创建。
这让我很疯狂。我为问题的长度道歉,但我想尽可能清楚明了。
END
==============================================================
此外,如果相关的话,这是dbInterface对象的代码。
function DatabaseInterface(db){
var DB = db;
this.sql = function(sql, arr, pSuccessHandler, pErrorHandler){
successHandler = (pSuccessHandler) ? pSuccessHandler : this.defaultSuccessHandler;
errorHandler = (pErrorHandler) ? pErrorHandler : this.defaultErrorHandler;
DB.transaction(function(tx){
if(!arr || arr.length == 0){
tx.executeSql(sql, [], successHandler, errorHandler);
}else{
tx.executeSql(sql,arr, successHandler, errorHandler)
}
});
}
// ----------------------------------------------------------------
// A Default Error Handler
// ----------------------------------------------------------------
this.defaultErrorHandler = function(transaction, error){
// error.message is a human-readable string.
// error.code is a numeric error code
console.log('WebSQL Error: '+error.message+' (Code '+error.code+')');
// Handle errors here
var we_think_this_error_is_fatal = true;
if (we_think_this_error_is_fatal) return true;
return false;
}
// ----------------------------------------------------------------
// A Default Success Handler
// This doesn't do anything except log a success message
// ----------------------------------------------------------------
this.defaultSuccessHandler = function(transaction, results)
{
console.log("WebSQL Success. Default success handler. No action taken.");
}
}