Javascript 通行证;这";在类中实例化的类

Javascript 通行证;这";在类中实例化的类,javascript,google-maps,Javascript,Google Maps,我是JavaScript新手,我正在尝试创建一个MapManager类,该类实例化一些其他管理器,这些管理器将管理Google地图的不同方面;例如标记、不同视图等 我遇到的问题是,当我试图将“this”作为参数传递给其他类时,MapManager正在实例化,它只传递MapManager的一个空实例(JavaScript控制台显示“MapManager{}”,调用MapManager类内声明的函数时出错。) 我不能在JavaScript中传递“this”以进行依赖项注入吗?如果您能够比较JavaS

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

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


我不能在JavaScript中传递“this”以进行依赖项注入吗?如果您能够比较JavaScript中的“this”与另一种语言之间的差异,那么知道我熟悉PHP、Java和Python可能会很有用。

您遇到的问题是,您在构造函数中使用的
this
实际上并不是您最终构建的东西。您正在使用一种特定的Javascript模式(您可能已经读过这种模式,认为它是实现“私有”成员的一种好方法),当您尝试使用该语言的某些功能时,它会导致奇怪的事情发生<代码>[0]

在构造函数执行期间,
实际上指向
MapManager
的一个实例。但是,由于要从构造函数返回对象,因此对
MapManager
实例的外部引用是对返回对象的引用,这与构造函数中引用的
this
不同

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

  • 如果您只是删除
    返回{…}并将在该对象中执行的赋值替换为,例如,
    this.functionName=functionName,你应该没事

  • 如果您想以更标准的JavaScriptish方式来实现,可以将
    map
    放在
    this
    上,并将方法放在
    MapManager.prototype
    上。解释如何执行此操作,以及这两个选项之间的差异

  • 此外,如果您对一个轻量级库感兴趣,它可以使定义经典OO类变得更容易,我建议您看看


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

    同意这种模式是邪恶的。尝试克隆这样的对象(使用var定义的所有内容只能在实例中访问)。尝试继承、重写和调用super.someMethod(这很痛苦)。它使用更多的CPU来创建和存储。仅仅拥有私有实例变量(当您使用返回闭包的函数设置prototype时,可以在JS中实现“私有”函数,但它更重)。我不会使用“private”,而只是用
    \u somePrivate
    标记它们。这正是我所做的——让它难看(并且众所周知是私有的),人们就不太可能使用它。如果他们真的使用它(而且他们可能有很好的理由这么做),他们至少会知道他们这样做是违反建议的。这不会解决你的问题,但会告诉你如何使用原型以及为什么。JS并不真正支持私有变量,我通常远离使用它们的模式。可以在原型上使用“私有”方法,但我也从未使用过:
    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
        };
    }