js单例——如何避免通过命名空间访问类成员

Posted

技术标签:

【中文标题】js单例——如何避免通过命名空间访问类成员【英文标题】:js singleton - how to avoid accessing class members via the namespace 【发布时间】:2011-12-31 20:32:54 【问题描述】:

我正在尝试改进我的 javascript 编码风格,并且一直在读到命名空间的东西很好。

但是,我似乎无法在任何我想使用的地方使用“this”关键字——相反,我只能从匿名函数中通过命名空间(在本例中为“oldMap”)访问我的类属性。这意味着我不能在不更改代码的情况下更改命名空间 id - 这似乎可能是错误的。

这是我构建的类 - 但它实际上似乎可以正常工作。 (对不起,它很长)。

任何关于我做对/错的建议/提示都非常感谢。谢谢

var oldMap = 

    map : null,

    center : lat:50, lng:20, zoom:3, 

    drawn : false,

    data : ,

    divId : "oldMap",

    url : "php/getMapData.php",

    infowindow : new google.maps.InfoWindow( 
        size: new google.maps.Size(150,50)
    ),

    init : function () 

        if (!this.drawn)
            $.getJSON(
                this.url,
                function(d)
                    if(d)
                        $.extend(oldMap.data,d);

                        var latlng = new google.maps.LatLng(oldMap.center.lat, oldMap.center.lng);
                        var myOptions = 
                            zoom: oldMap.center.zoom,
                            center: latlng,
                            mapTypeId: google.maps.MapTypeId.TERRAIN
                        ;

                        // create the map
                        map = new google.maps.Map(document.getElementById("oldMap"),myOptions);

                        // create the legend
                        var legendDiv = document.createElement('DIV');
                        legendDiv.innerhtml = '<div id="legend"><img src="images/markers/legend-blur.png"></div>';
                        map.controls[google.maps.ControlPosition.TOP_LEFT].push(legendDiv);

                        google.maps.event.addListener(map, 'click', function() 
                            infowindow.close();
                        );

                        // Set the info window html template
                        var infoWindowTemplate = "<div id='balloon'>#url2<img src='url2' />/url2<h2>project_name</h2><p><b>Amount</b> &euro; cost</p><p><b>Country</b> country</p><p><b>Year</b> year</p><p><b>Project Type</b> project_type</p><p>description</p>#url<p><a target='_blank' href='url'>More info</a></p>/url</div>"

                        // loop through the projects
                        for(var m in oldMap.data) 

                            // if the project has a marker type defined
                            if (oldMap.data[m].marker) 

                                // point
                                var point = new google.maps.LatLng(oldMap.data[m].lat, oldMap.data[m].longtd); 

                                // create HTML for info window
                                var infoHtml = Mustache.to_html(infoWindowTemplate, oldMap.data[m]);

                                // icon
                                var icon = new google.maps.MarkerImage(
                                    "images/markers/33px/" + oldMap.data[m].marker + ".png",
                                    new google.maps.Size(33,33)
                                );

                                // create a marker for this project
                                var marker = oldMap.createMarker(point,infoHtml,icon);
                            
                        

                        oldMap.drawn = true;
                    
                
            )
        
    ,


    createMarker : function (latlng, html, icon) 

        // create the marker
        var marker = new google.maps.Marker(
            position: latlng,
            icon: icon,
            map: map,
            zIndex: Math.round(latlng.lat()*-100000)<<5
        );

        // open info window when marker clicked
        google.maps.event.addListener(marker, 'click', function() 
            oldMap.infowindow.setContent(html); 
            oldMap.infowindow.open(map,marker);
        );
    

;

【问题讨论】:

【参考方案1】:

直接在对象上的函数的第一行应该是...

function () 
    var that = this;
    ...

然后,在你的内部函数中,将this 的引用替换为that

这是因为内部函数的this 指向window

【讨论】:

【参考方案2】:

如果您正在使用 jQuery,请查看 proxy() 方法:

http://api.jquery.com/jQuery.proxy/

此方法专门设计用于将this 的范围强制为特定对象。我个人更喜欢PrototypeJS bind()的语法:

http://api.prototypejs.org/language/Function/prototype/bind/

...虽然我更喜欢 PrototypeJS 而不是 jQuery,但似乎这场战斗已经打了又输了。

【讨论】:

以上是关于js单例——如何避免通过命名空间访问类成员的主要内容,如果未能解决你的问题,请参考以下文章

命名空间

命名空间

C++命名空间成员访问不同文件如何? “命名空间标准”是如何实现的?

C ++:使类及其某些数据成员仅在命名空间中可用

访问修饰符,命名空间

python命名空间,类成员,对象成员