访问JavaScript对象内的函数

4

我有一个问题,无法访问对象内的函数。

我的设置如下:

google.setOnLoadCallback(function(){$(document).ready(CareersInit);});

function CareersInit()
{
     CAREERS = new Careers();
     CAREERS.init();
}

function Careers()
{
     this.init = function()
     {
         function initialize() 
         {
             //Usual google maps stuff here
         }
     }

    $('body').bind('onload', function() {
        initialize();
    });
}

使用这种设置,初始化不会运行,但是如果我将我的谷歌地图变量/函数从初始化函数中拿出来,那么它可以工作,但是从谷歌文档中的理解(包含谷歌地图变量/函数等),初始化应始终是一个函数。即使这是正确的方法,找出如何在对象方法内部访问函数仅用于调试目的也是很好的。我认为。
CAREERS.init.initialize(); 

虽然这样写可以工作,但实际上并没有。

非常感谢任何帮助和建议。

谢谢。

Giles

2个回答

3
< p > initialize 函数是真正私有的,只能在你放置在 this.init 上的函数中访问它。除非你做些事情使其可访问,否则无法从 this.init 外部访问它。

但我认为您不需要那个额外的间接层:

google.setOnLoadCallback(function(){$(document).ready(CareersInit);});

function CareersInit()
{
     CAREERS = new Careers();
     CAREERS.init();
}

function Careers()
{
    var self = this;

    this.init = function()
    {
        //Usual google maps stuff here
    };

    $('body').bind('onload', function() {
        self.init();
    });
}

然而,您的代码试图两次初始化 Careers 实例。您有 Google 的加载回调调用 jQuery 的 ready 函数,该函数然后调用您的 CareersInit 函数,该函数调用 CAREERS.init。但是您还计划了一个单独的页面加载回调来调用 Careers 构造函数。(那个可能会运行,也可能不会,这取决于 Google 何时触发 setOnLoadCallback 回调。)

我会摆脱其中一个对 init 的调用。

在另一个答案的评论中,您说想知道最好的方法是什么。我需要了解更多关于您正在做什么的信息,但我可能会这样做:

(function() {
    // Our single Careers instance
    var CAREERS;

    // Ask Google to call us when ready
    google.setOnLoadCallback(function(){
        // Just in case Google is ready before the DOM is,
        // call our init via `ready` (this may just call
        // us immediately).
        $(document).ready(CareersInit);
    });

    // Initialize our single instance    
    function CareersInit()
    {
         CAREERS = new Careers();
         CAREERS.init();
    }

    // Constructor    
    function Careers()
    {
    }

    // Career's init function
    Careers.prototype.init = Careers_init;
    function Careers_init()
    {
        //Usual google maps stuff here
    }

})();

......除非你只需要一个实例(并且确定不会改变),否则根本不需要构造函数:

(function() {
    // Our data; the function *is* the single object
    var someData;

    // Ask Google to call us when ready
    google.setOnLoadCallback(function(){
        // Just in case Google is ready before the DOM is,
        // call our init via `ready` (this may just call
        // us immediately).
        $(document).ready(CareersInit);
    });

    // Initialize our single instance    
    function CareersInit()
    {
         someData = "some value";
    }
})();

在这里,函数作用域是单个实例;不需要单独的构造函数,使用this玩游戏等。请注意,我们没有创建任何全局变量,someData被限定在匿名函数中。解释器调用该函数时,我们得到了单个对象。
如果您需要多个Career实例,那么很好,请确保使用构造函数路线。但如果不需要,如果您使用已经拥有的对象(函数调用的执行上下文),则会少费事。

离题:强烈建议声明你的CAREERS变量。以你现在的代码为例,你正在成为隐式全局变量的恐怖的牺牲品。


谢谢您的帮助和有关self.init()的好建议。不过,我有一个问题:为什么这必须分配给一个变量? - Giles Butler
@Giles:因为在 JavaScript 中,this 不像你可能使用过的其他语言中的 this,比如 Java、C++、C# 等等。在 JavaScript 中,this 完全是由函数被调用的方式定义的,而不是函数的定义位置。当 jQuery 调用你的 onload 处理程序时,它会将 this 设置为 window 对象,而不是你的 Career 实例。所以我们利用了这个事实,你已经将处理程序定义为一个闭包,它位于构造函数调用的上下文中,并使用变量来记住对正在构造的对象的引用。(有关 this 的链接请参见我添加的链接。) - T.J. Crowder
@Giles:别担心,很高兴能帮到你。请注意,this不是jQuery的,而是JavaScript的。jQuery使用它的方式与任何JavaScript代码一样,因为JavaScript使我们对其有如此多的控制权。 :-) - T.J. Crowder
我刚刚更深入地了解了构造函数,所以现在它开始变得更加清晰了。我肯定只会有一个职业实例,所以我选择了你提供的第二个示例。我不太确定你所说的“我们的数据;函数单个对象”是什么意思,以及为什么要设置“someData”变量,这样其他函数是否可以访问它?在我的当前CareersInit的this.init函数中,我有所有通常的变量和函数来设置谷歌地图,例如mapoptions和geocoding函数,那么我应该把所有这些都放在“someData”变量里面吗?谢谢 - Giles Butler
@Giles:关于 someData,我假设你需要有一些持久状态。如果不需要,那就在作用域函数中不要有任何变量。当我说调用函数就是对象时,我是字面意思:每次调用函数都会创建一个执行上下文,其中(手势)保存了函数内的变量等内容。只要有任何东西引用它(如回调函数),即使函数已经返回,该上下文仍然存在。更多信息请参见:http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html - T.J. Crowder
显示剩余2条评论

0

initializeinit 内部的私有函数,这意味着它在 init 外部是无法访问的。

定义两次的目的到底是什么?

 this.init = function()
 {
         //Usual google maps stuff here
 }

没有特定目的,我只是想知道最好的方法,感谢您的帮助。 - Giles Butler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接