我目前正在使用JavaScript学习OOP。我正在重构一个应用程序而且我遇到了问题。
我创建了一个Class" Weather"
class Weather {
constructor({longitude, latitude} = {}) {
this.longitude = longitude;
this.latitude = latitude;
this.options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
}
getLongitude(){
return this.longitude;
}
setLongitude(longitude){
this.longitude = longitude;
}
getLatitude(){
return this.latitude;
}
setLatitude(latitude){
this.latitude = latitude;
}
getLocation() {
if (Modernizr.geolocation) {
//if locatin is enabled, show position in button
navigator.geolocation.getCurrentPosition(this.success, this.fail, this.options);
} else {
alert("Sorry, you browser doesn't have geolocation");
}
}
success(position){
let pos = position.coords;
console.log('Your actual position is :');
console.log(`Latitude : ${pos.latitude}`);
console.log(`Longitude: ${pos.longitude}`);
console.log(`More or less ${position.coords.accuracy} meters.`);
this.setLongitude(pos.longitude); // <== Doesn't work
this.setLatitude(pos.latitude); // <== Doesn't work
}
fail(){
console.log('User refused to give position');
}
}
一切正常,我可以像那样检索经度和纬度
let City = new Weather();
City.getLocation(); //will call getLocation and on success, it will console.log the longitude and latitude
我的问题是我可以更新我的对象的值。当我创建我的对象时,如果它们作为参数传递,则构造函数定义经度和纬度。但是,在成功方法中,我无法重新分配对象的值。
有没有解决方案?
答案 0 :(得分:2)
您已丢失了上下文,因为success
方法已作为参考传递。因此调用它时this
的值不会引用Weather
实例。您可以使用Function.prototype.bind
方法来解决此问题:
class Weather {
...
getLocation() {
if (Modernizr.geolocation) {
//if locatin is enabled, show position in button
navigator.geolocation.getCurrentPosition(
this.success.bind(this),
this.fail,
this.options
);
} else {
alert("Sorry, you browser doesn't have geolocation");
}
}
...
}
或者,您可以在构造函数中绑定方法,以便在实例化对象时仅调用bind
一次。
答案 1 :(得分:0)
正如克里斯沃克斯所说,你正在和#34;这个&#34;成功函数中的值
有几种方法可以解决它,问题是当navigator.geolocation.getCurrentPosition调用成功时,它会设置一个不同的&#34;这个&#34;您期望在函数上的值
一个可能是
var me = this;
navigator.geolocation.getCurrentPosition(function(position) {
me.success(position)
}, this.fail, this.options)
你对this.fail有同样的问题
另一种方式是
navigator.geolocation.getCurrentPosition(this.success.bind(this), this.fail.bind(this), this.options)
您可以从此处了解更多信息
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
编辑:由于第一个解决方案是错误的,所以需要一个指向这个的指针
答案 2 :(得分:0)
您可以使用类javascript的getter和setter。
class Weather {
constructor({longitude, latitude} = {}) {
this.longitude = longitude;
this.latitude = latitude;
...
}
get Latitude(){return this.latitude};
set Latitude(args){this.latitude=args};
...
}
答案 3 :(得分:0)
首先:虽然仍然可以在JavaScript中模仿OOP,但您应该避免使用此方法,而是选择Functional Programming。
回答你的问题:当你调用success()
时,正如JS中的每个函数一样,上下文发生了变化,this
将指向你调用代码的任何地方。
要解决此问题,您可以使用bind(this)
或将success
更改为方法而不是函数。以下是如何做到的:
successs: function(position){
let pos = position.coords;
console.log('Your actual position is :');
console.log(`Latitude : ${pos.latitude}`);
console.log(`Longitude: ${pos.longitude}`);
console.log(`More or less ${position.coords.accuracy} meters.`);
this.setLongitude(pos.longitude); // This will work now because this
this.setLatitude(pos.latitude); // will be referring to the Weather object
}
有关this
如何在JS工作的更多信息,请查看以下解释:http://blog.andrewray.me/react-es6-autobinding-and-createclass/