Javascript 回调创建无限循环

Javascript 回调创建无限循环,javascript,jquery,jquery-ui,Javascript,Jquery,Jquery Ui,如果第99行未注释,此代码将为对话框的第二次调用创建一个无休止的循环。我不明白确切的原因。 显然,这是因为在第95行中,“myCallback”在下面得到了“save.callback”,因此从自身调用。但为什么它不被选项中的实际内容覆盖呢 如何修复此代码 下面是一个关于JSFIDLE的工作示例: 代码如下: function Sandbox() { // turning arguments into an array var args = Array.prototype.sli

如果第99行未注释,此代码将为对话框的第二次调用创建一个无休止的循环。我不明白确切的原因。 显然,这是因为在第95行中,“myCallback”在下面得到了“save.callback”,因此从自身调用。但为什么它不被选项中的实际内容覆盖呢

如何修复此代码

下面是一个关于JSFIDLE的工作示例:

代码如下:

function Sandbox() {
    // turning arguments into an array
    var args = Array.prototype.slice.call(arguments),
        // the last argument is the callback
        callback = args.pop(),
        // modules can be passed as an array or as individual parameters
        modules = (args[0] && "string" === typeof args[0]) ? args : args[0],
        i;

    // make sure the function is called
    // as a constructor
    if (!(this instanceof Sandbox)) {
        return new Sandbox(modules, callback);
    }

    // add properties to 'this' as needed:
    this.a = 1;
    this.b = 2;

    // now add modules to the core 'this' object
    // no modules or "*" both mean "use all modules"
    if (!modules || '*' === modules) {
        modules = [];
        for (i in Sandbox.modules) {
            if (Sandbox.modules.hasOwnProperty(i)) {
                modules.push(i);
            }
        }
    }

    // initialize the required modules
    for (i = 0; i < modules.length; i += 1) {
        Sandbox.modules[modules[i]](this);
    }

    // call the callback
    callback(this);

    // any prototype properties as needed
    Sandbox.prototype = {
        name: "Sandbox",
        version: "1.0",
        getName: function () {
            return this.name;
        }
    }
};

var box = {};

Sandbox.modules = {};

Sandbox.modules.news = function (box) {
    var box = box || {},
    dialog = null;

    box.removeDialog = function (object) {
        var dialog = object || box.dialog;
        dialog.remove();
    };

    box.getEntries = function (options) {
        var color = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
        $('#main').css('color', color);
    };

    box.editEntry = function (options) {
        var triggerElement = options.triggerElement
        save = options.save;

        triggerElement.live('click', function () {
            box.displayDialog({
                save: save
            });
        });
    };

    box.displayDialog = function (options) {
        var save = options.save || null,
            dialog = $('<div id="dialog-modal">loading</div>');

        box.dialog = dialog;

        dialog.html('<button id="save" class="save">Save</button>')
            .dialog({
            modal: true,
            autoOpen: false,
            height: 'auto',
            position: 'top'
        }).dialog('open');

        // do we have a save function?
        if (null != save) {
            var buttonSave = $('button.save', dialog);
            myCallback = save.callback;
            save.callback = function () {
                box.removeDialog(dialog);
                if (myCallback != undefined && typeof myCallback == 'function') {
                    //myCallback(); // creates an endless loop
                }
            };

            buttonSave.on('click', function () {
                box.updateData(save);
            });
        }
    };

    box.updateData = function (options) {
        var callback = options.callback;
        $('#footer').append('<p>ok</p>');
        if (callback != undefined && typeof callback == 'function') {
            callback();
        }
    }
}

// page ready
$.ready(
Sandbox(['news'], function (box) {
    var getEntries = function () {
        box.getEntries();
    };
    box.getEntries();

    box.editEntry({
        triggerElement: $('#main'),
        save: {
            callback: getEntries
        }
    });
}));
函数沙盒(){
//将参数转换为数组
var args=Array.prototype.slice.call(参数),
//最后一个参数是回调
callback=args.pop(),
//模块可以作为数组或单个参数传递
模块=(args[0]&&“string”==typeof args[0])?args:args[0],
我
//确保调用了该函数
//作为构造器
如果(!(此实例为沙盒)){
返回新沙盒(模块、回调);
}
//根据需要将属性添加到“this”:
这是a=1;
这是b=2;
//现在将模块添加到核心“this”对象
//无模块或“*”都表示“使用所有模块”
如果(!modules | |'*'==模块){
模块=[];
用于(沙盒中的i.modules){
if(Sandbox.modules.hasOwnProperty(i)){
模块推送(i);
}
}
}
//初始化所需的模块
对于(i=0;i”);
if(callback!=未定义&&typeof callback=='function'){
回调();
}
}
}
//页面就绪
美元准备好了吗(
沙盒(['news'],函数(框){
var getEntries=函数(){
box.getEntries();
};
box.getEntries();
box.editEntry({
triggerElement:$(“#main”),
保存:{
回调:getEntries
}
});
}));

我发现了问题!这只是一个简单的打字错误。而不是“我写了一个”;“让“我的回调”进入全局范围

这:

必须替换为以下内容:

// do we have a save function?
if (null != save) {
    var buttonSave = $('button.save', dialog),
    myCallback = save.callback;
    save.callback = function () {
        box.removeDialog(dialog);
        if (myCallback != undefined && typeof myCallback == 'function') {
            //myCallback(); // creates an endless loop
        }
    };

    buttonSave.on('click', function () {
        box.updateData(save);
    });
}

我已经在第99行取消了代码注释,并且能够多次打开对话框,至少在Chrome中是这样。您是否可以提供一些其他信息来帮助我们复制这个问题?我在Firefox20.0 Windows和Ubuntu以及Internet Explorer中都有这个问题。如果在第99行之前执行“console.log(myCallback)”,它将输出一个函数[无限次]。我可以在firebug中点击它,并在第98行登陆。在Chrome中,在第二次调用后,保存操作非常缓慢。但它仍然有效,显然Chrome阻止了无休止的循环,只是默默地取消了请求。
// do we have a save function?
if (null != save) {
    var buttonSave = $('button.save', dialog),
    myCallback = save.callback;
    save.callback = function () {
        box.removeDialog(dialog);
        if (myCallback != undefined && typeof myCallback == 'function') {
            //myCallback(); // creates an endless loop
        }
    };

    buttonSave.on('click', function () {
        box.updateData(save);
    });
}