2014-04-18 3 views
0

지도 클래스 작동하지 '이'범위 : mapObject.getUserPosition() 내가 this.userLatitudethis.userLongitude을 점검 한 0을 반환하는 이유자바 스크립트 OOP

var mapObject = new Map(); 
console.log(mapObject.getUserPosition()); // Why does this return 0??? 

내가 알아낼 수 없습니다 : 개체 호출

function Map() { 
    this.map; 
    this.userLatitude = 0; 
    this.userLongitude = 0; 

    this.startPositionReporting(); 
} 

Map.prototype.getUserPosition = function() { 
    alert(this.userLatitude); 

    return { 
     latitude: this.userLatitude, 
     longitude: this.userLongitude 
    }; 
}; 

Map.prototype.startPositionReporting = function() { 
    var geolocationOptions = { 
     enableHighAccuracy : true 
    }; 

    function showError(error) { 
     switch(error.code) { 
      case error.PERMISSION_DENIED: 
       alert("User denied the request for Geolocation."); 
       break; 
      case error.POSITION_UNAVAILABLE: 
       alert("Location information is unavailable."); 
       break; 
      case error.TIMEOUT: 
       alert("The request to get user location timed out."); 
       break; 
      case error.UNKNOWN_ERROR: 
       alert("An unknown error occurred."); 
       break; 
     } 
    } 

    if (navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(function(position) { 
      this.userLatitude = position.coords.latitude; 
      this.userLongitude = position.coords.longitude; 
     }, null, geolocationOptions); 
    } 
}; 

startPositionReporting 메서드 내부에 있으며 제대로 작동합니다. 이것은 범위와 관련이 있어야합니다 ... 어떤 아이디어입니까?

+0

빠른 생각 ... 그것은 범위 문제처럼 보인다. 네비게이터 코드 앞에'var _this = this;'를 넣고 리턴 함수에서'this '를'_this'로 변경하십시오. –

답변

2

몇 가지. 문제는 this이 생각하는 것처럼 행동하지 않는다는 것입니다.

this은 함수의 범위에 바인딩되며 동적으로 (함수가 호출 될 때) 확인됩니다.

귀하의 문제는 당신이 인스턴스로 this 기대, 그 함수에서, 당신은 this의 속성을 설정하는 navigator.geolocation.getCurrentPosition, 공급 콜백을 가지고 있다는 것입니다.

그렇지 않습니다.

this은 가장 가능성이 높은 window입니다.

두 솔루션은 다음과 같습니다

Map.prototype.startPositionReporting = function() { 
    var map = this; // instance of Map 

    /* ... */ 
    navigator.geolocation.getCurrentPosition(function (position) { 
     map.userLatitude = position.coords.latitude; 
     // ... 
    }); 

또는

var updateMapCoords = function (position) { 
     this.userLatitude = position.coords.latitude; 
     // ... 
}; 


Map.prototype.startPositionReporting = function() { 
    var map = this; // instance of Map 
    var updateMap = updateMapCoords.bind(map); 
    // returns a copy of the function with `this` set to the value passed to `bind` 
    // ... 

    navigator.geolocation.getCurrentPosition(updateMap); 
    // ... 
0

navigator.geolocation.getCurrentPosition은 비동기 함수입니다. 해당 필드가 0이 아닌 다른 값이되기 전에 반환 될 때까지 기다려야합니다.

+0

기다렸다가 포지션이 할당 된 후 함수를 호출했는지 확인했습니다. – jskidd3

+0

문제를 나타내는 jsfiddle을 게시 할 수 있습니까? –

2

예 범위 문제입니다.

var that = this; 

    if (navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(function(position) { 
      that.userLatitude = position.coords.latitude; 
      that.userLongitude = position.coords.longitude; 
     }, null, geolocationOptions); 
    } 

getCurrentPosition에서 전달하는 함수는 다른 컨텍스트에서 호출됩니다. 그래서 그 함수가 호출 된 컨텍스트에 대한 참조를 저장해야합니다. 당신이 당신의 익명 함수 내부의 this 변수가 여전히지도 객체를 참조한다고 가정 -method

+0

건배! 완벽하게 일했습니다. – jskidd3

0

귀하의 문제는 startPositionReporting의이 부분에서

if (navigator.geolocation) { 
    navigator.geolocation.getCurrentPosition(function(position) { 
     this.userLatitude = position.coords.latitude; 
     this.userLongitude = position.coords.longitude; 
    }, null, geolocationOptions); 
} 

간단하다. 음, 그렇지 않습니다. 당신은 명시 적 변수에 사용할 범위를 저장해야 다음과 같이 익명 함수 클로저 내에서 사용이 도움이

var self = this; 

if (navigator.geolocation) { 
    navigator.geolocation.getCurrentPosition(function(position) { 
     self.userLatitude = position.coords.latitude; 
     self.userLongitude = position.coords.longitude; 
    }, null, geolocationOptions); 
} 

희망을!

관련 문제