0

我写了两个对象。一个叫做List,另一个叫做Car。

function Car()
{
  this.make="";
  this.year="";
}

function List()
{
  this.cars = [];
}

我还有另一个函数,它是一个对象 List 的方法,用于读取 XML 文件的信息,并将它们存储在 List 对象内的汽车数组中:

List.prototype.readXML = function()
{
  var i = 0;
  $.get('mydata.xml', function(xml){
    $(xml).find("item").each(function(){
      //Bug Point!!!
      this.cars.push(new Car()); //Push a Car object into array
      this.cars[i].ID = ($(this).attr("ID"));
     }); 
   });
 }

但是,这行不通。每次调试都让我没有定义汽车...我尝试使用 var 而不是这个来定义汽车。并试图删除 this.cars.push 而不是 cars.push。但它仍然说汽车没有定义。

我假设我可能在这个问题中的变量范围有问题。谁能教我怎么做?

谢谢!

4

3 回答 3

2

问题出在你的 jquery 上

$.get('mydata.xml', function(xml){
    $(xml).find("item").each(function(){
      //Bug Point!!!
      this.cars.push(new Car()); //Push a Car object into array
      this.cars[i].ID = ($(this).attr("ID"));
     }); 
   });

this不指您期望它指的内容

克服这个问题的一种常见方法是将它分配给一个不同的变量,称为thatself

List.prototype.readXML = function()
{
  var i = 0;
  // Create a new variable called 'self' that you can refer to within different function scopes
  var self = this;
  $.get('mydata.xml', function(xml){
    $(xml).find("item").each(function(){
      self.cars.push(new Car()); //Push a Car object into array
      self.cars[i].ID = ($(this).attr("ID"));
     }); 
   });
 }

这意味着您可以访问您需要访问的原始 List 对象。这种方法利用了闭包。

希望这可以帮助


编辑评论中提出的解释性问题:

List.prototype.readXML = function()
{
  // Create a new variable called 'self' that you can refer to within different function scopes
  var self = this;
  $.get('mydata.xml', function(xml){
    $(xml).find("item").each(function(i, domElem){
      var car = new Car();
      car.id = $(domElem).attr("ID");
      self.cars.push(car); //Push a Car object into array
     }); 
   });
 }
于 2012-08-20T22:46:15.523 回答
1

您遇到的问题与闭包有关。

基本上,这在您的 .each 语句中发生了变化。.each 不再指代 List,它指的是 XML 中的当前“项目”。

要修复它,请参阅JavaScript 闭包如何工作?

List.prototype.readXML = function()
{
  var i = 0;
  var self = this;
  $.get('mydata.xml', function(xml){
    $(xml).find("item").each(function(){
      //Bug Point!!!
      self.cars.push(new Car()); //Push a Car object into array
      self.cars[i].ID = ($(this).attr("ID"));
     }); 
   });
}
于 2012-08-20T22:46:28.380 回答
1

问题是this上下文随着 Ajax 回调而改变。我会在原型上定义一个addCar方法,并使用它来添加新车。像这样的东西:

List.prototype.addCar = function(data) {
  this.cars.push(new Car()); //Push a Car object into array
  this.cars[i].ID = ($(data).attr("ID"));
}

List.prototype.readXML = function()
{
  var i = 0;
  var self = this;
  $.get('mydata.xml', function(xml){
    $(xml).find("item").each(function(){ self.addCar(this); });
   });
 }
于 2012-08-20T22:48:23.827 回答