Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以再次调用已初始化的对象吗?_Javascript_Constructor - Fatal编程技术网

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

Javascript 我可以再次调用已初始化的对象吗?,javascript,constructor,Javascript,Constructor,我有一个JavaScript构造函数,我想首先使用它通过Ajax异步获取一些数据,完成后,再次调用它自己来操作获取的数据。这基本上意味着再次调用构造函数的同一个实例,但我无法让它工作。以下是我试图做的一个框架: function ajaxmenu(file){ var filefetched = false var instance = this // save reference to this instance of ajaxmenu if (!filefetched

我有一个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获取文件的部分,然后一旦完成,再次调用
ajaxmenu()
的相同实例,但这一次,文件已经就位,用于提醒要解析和操作的函数


我该怎么做?现在调用
instance()
返回一个错误。

一般来说,您的问题
是否可以再次调用初始化对象的答案是肯定的!你有很多选择

如果您坚持再次使用相同的函数,那么一个选项是

  • 将第二个参数
    filefetched
    添加到
    ajaxmenu
  • 您不需要
    var instance=this
  • 从自身调用
    ajaxmenu
    时传递
    true
    ,以跳过获取:
    ajaxmenu(文件,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提供的回调,并在
done
事件中对菜单进行更改,该事件在
get
函数完成后执行。这样,您就不需要递归调用:

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);
这也大大简化了代码,因为您不需要分支(和/或递归调用),而且它更具可读性,因此更易于维护

通常在递归调用上:您总是需要一个条件来停止递归,以防止出现无限循环。一种可能是使用一个参数,该参数在每次新的递归调用时都会更改:

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); 

感谢Pasty,您的解决方案是一个良好的开端,尽管当
ajaxmenu(file,true)时
在ajax函数中被调用,它实际上并没有调用我需要的先前实例化版本的
ajaxmenu()
。我需要在最后使用
return
在ajax函数内部进行分支,以便在获取文件(当文件中的元素可用时)之前不会调用构造函数的提醒。如果我只是调用
ajaxmenu(文件,true)第二次,对象
this
指向全局对象,而不是先前启动的对象。我知道第二种方法,但我希望避免将所有内容都放在回调函数中。请查看JavaScript中的
this
关键字。它在JavaScript中的行为与在C/C++/Java/C中不同,因为JavaScript使用词法范围。如果要使用
实例,请将其作为参数传递给
ajaxmenu