将“this”传递给在类中实例化的类

时间:2013-08-27 19:52:49

标签: javascript google-maps

我是JavaScript的新手,我正在尝试创建一个MapManager类来实例化一些其他管理器,这些管理器将管理Google地图的不同方面;如标记,不同视图等。

我遇到的问题是当我尝试将“this”作为参数传递给其他类时,MapManager正在实例化,它只传递一个MapManager的空实例(JavaScript控制台显示“MapManager {} “我在调用MapManager类中声明的函数时遇到错误。)

var MapManager = function(map) {

    var markerManager = new MarkerManager(this);
    var viewManager = new ViewManager(this);

    var getMarkerManager = function() {
        return markerManager;
    }

    var getViewManager = function() {
        return viewManager;
    }

    var getMap = function() {
         return map;
    } 

    return {
        getMarkerManager: getMarkerManager,
        getViewManager: getViewManager,
        getMap: getMap
    }

}

var MarkerManager = function(mapManager) {

    var map = mapManager.getMap();
    var markers = {};

    var createMarker = function(id, latitude, longitude) {

        var marker = new google.maps.Marker({
        position: new google.maps.LatLng(latitude, longitude),
        map: map,
        animation: google.maps.Animation.DROP
        });

        marker.set("id", id);
        markers[id] = marker;

        var listener = new google.maps.event.addListener(marker, "click", function () {
             mapManager.getViewManager().setZoomToClient(id);
        };
    };

    return {
        createMarker: createMarker
    };
}

var ViewManager = function(mapManager) {

    var map = mapManager.getMap();
    var setBoundView = function() {
    var bounds = new google.maps.LatLngBounds();
    var markers = mapManager.getMarkerManager.getMarkers();
    for(id in markers) {
    bounds.extend(markers[id].getPosition());
    }
    map.fitBounds(bounds);
    };

    return {
    setBoundView: setBoundView
    };
}

我无法在JavaScript中为依赖注入传递“this”吗?如果您能够比较JavaScript中“this”与其他语言之间的差异,那么了解我熟悉PHP,Java和Python可能会很有用。

2 个答案:

答案 0 :(得分:2)

您遇到的问题是,您在构造函数中使用的this实际上并不是您最终构建的内容。您正在使用特定的Javascript模式(您可能已经将其视为实施"私有"成员的一种好方法),当您尝试使用某些功能时,会导致奇怪的事情发生语言。 [0]

在构造函数执行期间,this实际上指向MapManager的实例。但是,因为您要从构造函数返回一个对象,所以对MapManager实例的外部引用是对返回的对象的引用,这与this的{​​{1}}不同。你在构造函数中引用了它。

有几种方法可以解决这个问题:

  1. 如果您只是从构造函数中删除return { ... };并将您在该对象中执行的分配替换为例如this.functionName = functionName;,那么您应该没问题。

  2. 如果您想以更标准的JavaScript方式执行此操作,可以将map放在this上,并将方法放在MapManager.prototype上。 This SO question解释了如何执行此操作,以及有关这两个选项之间差异的更多信息。

  3. 此外,如果您对轻量级库感兴趣,这样可以更轻松地定义经典OO类,我建议您查看Classy

    [0]我对这种模式有些自以为是:我认为它是邪恶的,邪恶的,破碎的,不应该被使用。它以特别令人沮丧的方式打破了语言的基本方面(如原型链)。

答案 1 :(得分:0)

您不应将this作为参数传递给班级的instance,有更好的方法来实现它。

首先,PHPJavascript之间最重要的区别是,在PHP中,您有一个继承,并且您不需要将引用传递给父类。

在javascript中它有点复杂,因为javascript在继承中不自然支持,你可以阅读我最喜欢的知识来源:

(解释如何实施) http://ejohn.org/blog/simple-javascript-inheritance/

回到您的问题,您可以使用

this传递给您的功能

Function.prototype.call

Function.prototype.apply

Function.prototype.bind - 从版本9开始的IE支持绑定

这些方法的主要缺点是你失去了对你的真实类的引用,这又是我第一段的回复,你应该实现继承。