2012-08-20 2 views
0

두 개체를 작성했습니다. 하나는 List이고 다른 하나는 Car입니다.javascript 및 jQuery의 중첩 개체 함수의 변수 범위

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

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

내가 XML 파일의 정보를 읽고, 목록 개체 내부의 자동차 배열에 저장하는 객체 목록의 방법으로 다른 기능을 가지고 : 그러나

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 대신에 차를 정의하려고했습니다. cars.push 대신 this.cars.push를 제거하려고했습니다. 그러나 그것은 아직도 차가 정의되지 않는다고 말한다.

나는이 문제의 변수 범위에 문제가있을 수 있다고 생각합니다. 어느 누구도 저에게 그걸하는 법을 가르쳐 줄 수 있습니까?

감사합니다.

+0

어떻게 호출합니까? – Qnan

답변

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 당신이

이 문제를 극복하는 일반적인 방법라는 다른 변수에 할당됩니다를 참조하는 기대를 참조하지 않습니다 that 또는 원래 목록 개체 그쪽에 액세스 할 수있는 의미 self

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.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 
    }); 
    }); 
} 
+0

감사합니다. @ AlanFoster. 나는 그 도움을 생각한다. 이 자체 교환은이 문제를 극복하기위한 진정한 트릭입니다. 그러나 나는이 코드 줄로 다른 버그를 만난다고 생각한다. self.cars [i] .ID = ($ (this) .attr ("ID")); 나는 Car 객체를 투명한 선에 넣었으므로이 car [i] .ID 구문에서 멤버 (ID)에 액세스한다고 가정합니다. 맞습니까? 디버거가 방금 "Uncaught TypeError : 정의되지 않은 ID '속성을 설정할 수 없습니다."라고 알려 주셨습니다. 고맙습니다! – Arthur0902

+0

@ Arthur0902 과 같이 다시 쓸 수 있습니다. function (i, xml) { var car = new Car(); 자동차.id = $ (xml) .attr ("ID"); self.cars.push (car); }'각각의 'this'는 i의 값이고 dom 요소는 아닙니다 – AlanFoster

+0

@ Arthur0902 제가 제안한 것의 근원을 포함하도록 원래의 질문을 수정했습니다 – AlanFoster

1

은 당신이 발생하는 문제는 폐쇄 관련이있다 :

희망이 의견에 질문


편집 설명 질문을 할 수 있습니다.

기본적으로 .each 문 내부에서이 범위가 변경됩니다. .each는 List를 더 이상 참조하지 않고 XML 내부의 현재 "항목"을 참조합니다.

것은, 그것을 해결 문제는 상황은 아약스 콜백에 따라 변화한다는 것입니다 How do JavaScript closures work?

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")); 
    }); 
    }); 
} 
+0

매우 유용한 리소스를 제공해 주셔서 감사합니다. 정말 도움이되었습니다! – Arthur0902

1

참조하십시오. 프로토 타입에 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); }); 
    }); 
}