我可以再次调用初始化对象吗?

时间:2014-12-14 20:24:14

标签: javascript constructor

我有一个JavaScript构造函数,我想首先通过Ajax异步获取一些数据,一旦完成,再次调用自己来操作获取的数据。这基本上意味着再次调用构造函数的相同实例,但我不能让它工作。这是我正在尝试做的一个框架:

function ajaxmenu(file){
    var filefetched = false
    var instance = this // save reference to this instance of ajaxmenu
    if (!filefetched){
        $.get(file, function( data ){
            $(data).appendTo(document.body)
            filefetched = true
            instance() // how can I call instance again to initialize menu again now that ajax file is loaded?
            return
        })
    }

    this.menu = $('#menuid') // uses jQuery
    this.menu.css({width: '100px'})
    //do something else fancy with $menu
}

var menu = new ajaxmenu('menu.htm')

所以基本上我想要在这里发生的逻辑是,当ajaxmenu()被实例化时,ajaxmenu()内部通过Ajax获取某个文件的部分被调用,然后一旦完成,就会发生同一个{再次调用{1}},但这次已经存在文件,用于解析和操作函数的提醒。

我该怎么做?我现在所拥有的,调用ajaxmenu()会返回错误。

1 个答案:

答案 0 :(得分:1)

一般来说,问题Can I call an initialized object again的答案是肯定的!你有很多选择。

如果你坚持再次使用相同的功能,那么一个选项就是

  • filefetched
  • 添加第二个参数ajaxmenu
  • 您不需要var instance = this;
  • 从自己调用true时传递ajaxmenu,跳过提取:ajaxmenu(file, true);

完整代码:

function ajaxmenu(file, filefetched){
    if (!filefetched){
        $.get(file, function( data ){
            $(data).appendTo(document.body)
            ajaxmenu(file, true);
        });
    }

    this.menu = $('#menuid') // uses jQuery
    this.menu.css({width: '100px'})
    //do something else fancy with $menu
}

var menu = new ajaxmenu('menu.htm', false);

另一个选项(没有自我调用)将使用jQuery为get function提供的回调,并对done事件中的菜单进行更改,该事件在get事件中执行{1}}函数完成。这样您就不需要递归调用:

function ajaxmenu(file){
    $.get(file, function( data ){
        $(data).appendTo(document.body)
    })
    .done(function() {
        this.menu = $('#menuid') // uses jQuery
        this.menu.css({width: '100px'})
        //do something else fancy with $menu
    });
}

var menu = new ajaxmenu('menu.htm');

这也简化了代码,因为你不需要分支(和/或递归调用),而且它更易读,更易于维护。

通常在递归调用上:总是需要一个条件来停止递归以防止无限循环。一种可能性是使用每个新的递归调用更改的参数:

function process(data, n)
{
    // process data
    // iterate again or stop recursion
    if (n > 0)
    {
        process(data, n - 1);
    }
    // done => n = 0
}
// start
process(data, 5);

另一种选择是使用全局变量并跟踪它的状态,但这通常表明设计不好而且不建议使用:

// global variable
var n = 5;
function process(data)
{
    // process data
    // iterate again or stop recursion
    if (n > 0)
    {
        n = n - 1;
        process(data);
    }
    // done => n = 0
}
// start
process(data);