对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。
答案 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
。实际上,它最终会设置全局latitude
和longitude
变量,而不是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