代码之家  ›  专栏  ›  技术社区  ›  graham.reeds

JavaScript类中的范围问题

  •  2
  • graham.reeds  · 技术社区  · 15 年前

    我身上的古典程序员爱上了面向对象的公共/私有范式,我发现很难放弃。这使我遇到了一个我希望你能帮助我的问题。

    我有一个叫做map的单体物体。只能有一个。这张地图包含被称为星星的物体(这是一个游戏)。星星看起来像这样:

    var Star = function(id, x, y) {
        this.id_ = parseInt(id);
        this.x_ = parseInt(x);
        this.y_ = parseInt(y);
    };
    

    事实上,有更多的论据和属性。这只是一个例子。

    地图定义如下:

    var map = (function() {
        // public interface
        return {
            init: function() {
                getStars();         
            },
            stars: {} // works but publicly accessible
        };
    
        var stars = new Array(); // fail
    
        function getStars() {
            $.getJSON("ps.php?jsoncallback=?", addStars);
        }
    
        function addStars(data) {
            for (var x=0, xx=data.stars.length; x<xx; x++) {
                map.stars[data.stars[x].id] = new Star(
                    data.stars[x].id,
                    data.stars[x].xpos, 
                    data.stars[x].ypos
                );
            }
        }
    })();
    

    我认为由于 addStars 是的回调函数 $.getJSON 它不能将新创建的星添加到星的私有变量中(Firebug说它是未定义的,jquery调用到 abort 在它尝试添加它之后)。然而,如果我把星变成一个公开可见的对象,那么它确实起作用了,但是星从界面上是可见的,这不是我想要的。

    我如何保持stars的私密性,并从json回调中访问它?

    3 回复  |  直到 15 年前
        1
  •  2
  •   lincolnk    15 年前

    你可以参考 stars 没有 map 在它前面。

    var map = (function() { 
    
        var stars = new Array(); 
    
        function getStars() { 
            $.getJSON("ps.php?jsoncallback=?", addStars); 
        } 
    
        function addStars(data) { 
            for (var x=0, xx=data.stars.length; x<xx; x++) { 
                stars[data.stars[x].id] = new Star( 
                    data.stars[x].id, 
                    data.stars[x].xpos,  
                    data.stars[x].ypos 
                ); 
            } 
        } 
    
        // this should be at the bottom.
    
        // public interface 
        return { 
            init: function() { 
                getStars();          
            }
        }; 
    
    })(); 
    

    定义 addStars 在相同的范围上下文中 星星 创建一个闭包,使 星星 在调用函数时可用。

        2
  •  2
  •   gblazex    15 年前

    你在回归后定义了星星。它永远不会被创造出来 ,当然,它将是未定义的。

    [ See is in action ]

    var map = (function() {     
    
        var stars = new Array(); // define before return!
    
        function getStars() {
            $.getJSON("ps.php?jsoncallback=?", addStars);
        }
    
        function addStars(data) {
            for (var x=0, xx=data.stars.length; x<xx; x++) {
                stars[data.stars[x].id] = new Star( // use private stars
                    data.stars[x].id,
                    data.stars[x].xpos, 
                    data.stars[x].ypos
                );
            }
        }
    
        // public interface
        return {
            init: function() {
                getStars();         
            }
        };
    })();​
    
        3
  •  0
  •   roryf    15 年前

    尽管如此 stars 可以视为私有成员,它实际上只存在于定义 map . 因此,您不能通过 map.stars 但是,您可以简单地访问 星星 在回调函数中。

    var map = (function() {
    
        var stars = [];
    
        function getStars() {
            $.getJSON("ps.php?jsoncallback=?", function(data) {
                for (var x=0, xx=data.stars.length; x<xx; x++) {
                    stars[data.stars[x].id] = new Star(
                        data.stars[x].id,
                        data.stars[x].xpos, 
                        data.stars[x].ypos
                    );
                }
            });
        }
    
        // public interface
        return {
            init: function() {
                getStars();         
            }
        };
    })();
    
    推荐文章