无法在 $.post 回调中设置作用域变量

Can't set scoped variable in $.post callback

本文关键字:设置 作用域 变量 回调 post      更新时间:2023-09-26

我有以下类型的结构:

(function(){
var objects = [];
$('button.one').on('click', function(){
  fetchObjects = function(objects) {
    $.post("/fetchObjects")
      .done(function(data){
        objects = data;
        console.log(objects.length);
      });
  }
  fetchObjects(objects)
});
$('button.two').on('click', function(){
  console.log(objects.length);
});
})();

您可以看到我有一个变量objects是此函数的本地变量。最初它是空的。当我单击button.one时,我希望使用来自某个 ajax 请求的返回值填充objects。它似乎有效,但是当单击button.two时,objects变量仍然是一个空数组。

为什么 jQuery 回调中没有objects

我也尝试过这种方法,但结果相同:

function callback(data) {
  facilities = data
}
$.post("/fetchObjects")
.done(function(data){
  callback(data);
});

我在这里错过了什么?请不要告诉我将"对象"全局化。

我不知道

你为什么要将对象作为参数传递。我认为以下内容应该可以正常工作。如果您想实现其他目标,请告诉我。

(function(){
var objects = [];
$('button.one').on('click', function(){
  fetchObjects = function() {
    $.post("/fetchObjects")
      .done(function(data){
        objects = data;
        console.log(objects.length);
      });
  }
  fetchObjects()
});
$('button.two').on('click', function(){
  console.log(objects.length);
});
})();

让我们稍微简化一下代码。你基本上有这个:

var objects = [];
fetchObjects = function(innerObjects) {
  var data = ['a','b'];
  innerObjects = data;
  console.log(innerObjects.length);
};
fetchObjects(objects);
console.log(objects);

(为了清楚起见,我更改了另一个objects变量的名称;即使它具有相同的名称,问题也是相同的。

调用该函数时,innerObjects包含对objects的引用,因此修改它也会更改原始数组。但是当你这样做时

innerObjects = data;

现在,您不是修改数组,而是用其他内容替换引用。 innerObjects"点"到 data 而不是 objects,原始变量保持不变。

要使其正常工作,您需要遍历data数组(假设它始终是一个数组)并将内容逐个分配给objects引用。这样,您将保留原始引用并修改原始数组。

var objects = [];
fetchObjects = function(innerObjects) {
  var data = ['a','b'];
 
  for( var i = 0; i < data.length; i++ ) {
      innerObjects[i] = data[i];
  }
  console.log(innerObjects.length);
};
fetchObjects(objects);
console.log(objects);

或者,在您的实际代码中:

(function(){
var objects = [];
$('button.one').on('click', function(){
  fetchObjects = function(objects) {
    $.post("/fetchObjects")
      .done(function(data){
        for( var i = 0; i < data.length; i++ ) {
          objects[i] = data[i];
        }
        console.log(objects.length);
      });
  }
  fetchObjects(objects)
});
$('button.two').on('click', function(){
  console.log(objects.length);
});
})();