0

有点难以理解coffeescript。为什么这是 set_position 函数中的窗口对象?

window.App = {}

$ ->
  driver = new Driver if ($('#drivers_become').length >= 1)
  window.App.driver = driver

class Driver
  constructor: ->
    @get_position()
  get_position: ->
    if navigator.geolocation
      navigator.geolocation.getCurrentPosition(@set_position)
  set_position: (pos) ->
    # this refers to window object in this case. why?
    @latitude = pos.coords.latitude
    @longitude = pos.coords.longitude
  get_latitude: ->
    @latitude
  get_longitude: ->
    @longitude

在这种情况下,get_latitude 和 get_longitude 返回 undefined。

4

2 回答 2

1

如果您将aDriverInstance.set_position其用作事件处理函数,浏览器会将其作为常规函数而不是方法调用。要解决此问题,请在定义时使用“胖箭头”:set_position: (pos) =>. 但更广泛地说,这是一个通过点符号调用和通过直接引用调用的问题:

aDriverInstance.set_position(pos)this设置为aDriverInstance,一切都很好

set_position_reference = aDriverInstance.set_position;set_position_reference(pos)this设置为窗口对象。

于 2013-09-25T14:51:45.687 回答
0

这是一个经典的绑定问题,适用于 Javascript 和 Coffeescript。

您正在将一个Driver方法传递set_position给一个 Windows 函数,

navigator.geolocation.getCurrentPosition(@set_position)

set_position该函数在全局、窗口、上下文中进行评估。实际上,它最终设置了全局latitudelongitude变量,而不是Driver实例的属性。在您的控制台中查看是否定义了这些变量。

你想要做的是定义set_position所以@绑定到Driver实例。为此,请使用粗箭头=>http://coffeescript.org/#fat-arrow

set_position: (pos) =>
    # this refers to window object in this case. why?
    @latitude = pos.coords.latitude
    @longitude = pos.coords.longitude

如果你使用它,并查看编译后的 Coffee,你会看到这样一行:

this.set_position = __bind(this.set_position, this);

像 jquery 和 underscore 这样的包也有一个bind功能,最近的浏览器也有。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

get_position: ->
   if navigator.geolocation
       navigator.geolocation.getCurrentPosition(@set_position.bind(this))

使用浏览器的bind

于 2013-09-25T21:18:31.167 回答