在另一个方法JavaScript中调用一个方法

时间:2017-09-19 21:25:41

标签: javascript oop methods this

我目前正在使用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

我的问题是我可以更新我的对象的值。当我创建我的对象时,如果它们作为参数传递,则构造函数定义经度和纬度。但是,在成功方法中,我无法重新分配对象的值。

有没有解决方案?

4 个答案:

答案 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/

相关问题