coffeescript - 构造函数中设置的变量在不同方法中未定义

标签 coffeescript

我正在 CoffeeScript 中创建一个库,并使用 Google map 计算票价。

像这样初始化 map 时:

var viewport = document.getElementById('viewport'),
    options = {
        center: new google.maps.LatLng(-34.397, 150.644),
        zoom: 8
    };

google.maps.event.addDomListener(window, 'load', function()
{
    var map = new google.maps.Map(viewport, options);
});

它按预期加载。

但是当我使用我的库初始化它时:

var viewport = document.getElementById('viewport'),
    options = {
        center: new google.maps.LatLng(-34.397, 150.644),
        zoom: 8
    },

    map = new FareJS.Map(viewport, options);

视口(viewport)保持灰色,移动 map 会出现TypeError: a is undefined

经过一番研究,我发现Map类中的initializeMap方法中的@opt的值是未定义的。我觉得这很奇怪,因为我在构造函数中设置了它。更奇怪的是,@viewport不是未定义...只是@opt

有问题的类(class)是

class Map
    constructor: (@viewport, @opt) ->
        if not window.hasOwnProperty('google')
            throw "Google Maps API could not be found, are you sure you installed it?"

        @loadMapOnLoad()

    initializeMap: () ->
        @map = new google.maps.Map(@viewport, @opt)
        return

    loadMapOnLoad: () ->
        google.maps.event.addDomListener(window, 'load', @initializeMap)
        return

编译后如下所示:

var Map;

Map = (function() {
    function Map(viewport, opt) {
        this.viewport = viewport;
        this.opt = opt;
        if (!window.hasOwnProperty('google')) {
            throw "Google Maps API could not be found, are you sure you installed it?";
        } 
        this.loadMapOnLoad();
    }

    Map.prototype.initializeMap = function() {
        this.map = new google.maps.Map(this.viewport, this.opt);
    };

    Map.prototype.loadMapOnLoad = function() {
        google.maps.event.addDomListener(window, 'load', this.initializeMap);
    };

    return Map;

})();

为什么会这样?我该如何解决它?

最佳答案

问题是 initializeMap 将在类/对象的上下文之外执行。 this 不会引用 initializeMap 中的类实例。您必须执行以下操作之一:

# explicitly bind to @
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
google.maps.event.addDomListener window, 'load', @initializeMap.bind @

# preserve context with => and call regularly 
google.maps.event.addDomListener window, 'load', => @initializeMap()

# declare method with bound context, so it doesn't matter how you call it
# (resulting behaviour could be considered somewhat unidiomatic for JS, caveat emptor)
class Map
  initializeMap: =>
    ..

关于coffeescript - 构造函数中设置的变量在不同方法中未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29824916/

相关文章:

node.js - 保留 Async.js 中的范围

coffeescript - 有什么方法可以在没有括号的 CoffeeScript 中编写点属性?

javascript - Coffeescript 解析意外错误 '.'

node.js - 有没有办法为 require 注册新的 CoffeeScript 扩展?

javascript - 按特定顺序观看和编译多个文件夹中的 CoffeeScript 和 vendor javascript 文件,还组织 sass 和 html 模板

javascript - 如何为 CoffeeScript 设置 PHPStorm 文件观察器

javascript - 利用 d3 在 SVG 内渲染foreignObject 失败

javascript - ReactCompositeComponent.render() : A valid ReactComponent must be returned. 您可能返回了未定义的数组或其他一些无效对象

coffeescript - 如何使用 CoffeeScript 使用 `this` 和 `_this`(粗箭头)?

sql - CoffeeScript,寻找类似 SQL 的模块