为什么@在Coffeescript中引用Window对象?

时间:2013-09-25 13:49:42

标签: coffeescript

对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。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分: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

如果您使用它,并查看已编译的咖啡,您将看到一行:

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

像jquery和下划线这样的软件包也有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