How could I emulate the goto programming construct in this case?
$.fn.hierarchy = function(info, ret) {
    if (info.constructor !== Object) {
        info = {children: info};
        goto label1; // Illegal JavaScript
    }
    if (!info.children) {
        info.children = [];
        goto label2; // Illegal JavaScript
    }
    label1:
    if (info.children.constructor !== Array)
        info.children = [info.children];
    label2:
    /*
    // Forget this code. It's irrelevant to my specific problem
    // (which is that JS doens't allow non-nested conditionals)
    //  and caused much confusion.
    if (!info.tagc)
        info.tagc = info.tag || 'div';
    */
I know I could implement exactly ONE of these gotos as an else clause:
$.fn.hierarchy = function(info, ret) {
    if (info.constructor !== Object) {
        info = {children: info};
        //goto label1;
    }
    else if (!info.children) {
        info.children = [];
        goto label2; // Illegal JavaScript
    }
    //label1:
    if (info.children.constructor !== Array)
        info.children = [info.children];
    label2:
    /*
    // Forget this code. It's irrelevant to my specific problem
    // (which is that JS doens't allow non-nested conditionals)
    //  and caused much confusion.
    if (!info.tagc)
        info.tagc = info.tag || 'div';
    */
Or:
$.fn.hierarchy = function(info, ret) {
    if (info.constructor !== Object) {
        info = {children: info};
        goto label1; // Illegal JavaScript
    }
    if (!info.children) {
        info.children = [];
        //goto label2;
    }
    else {
        label1:
        if (info.children.constructor !== Array)
            info.children = [info.children];
    }
    //label2:
    /*
    // Forget this code. It's irrelevant to my specific problem
    // (which is that JS doens't allow non-nested conditionals)
    //  and caused much confusion.
    if (!info.tagc)
        info.tagc = info.tag || 'div';
    */
But I want to have both gotos. And, no, I don't want additional flags.
EDIT:
@Luis Espinal: Your proposed solution doesn't work. If info is {children: 'a'}, your program fails to convert info.children to [a].
$.fn.hierarchy = function(info, ret) {
    if (info.constructor !== Object) {
        info = {children: info};
        // goto label1; // Illegal JavaScript
        // label1:
        if (info.children.constructor !== Array){
            info.children = [info.children];
        }
    }
    else if (!info.children) {
        info.children = [];
        // goto label2; // Illegal JavaScript
        // label2:
        /*
        // Wrong. This has to be placed outside all of this.
        if (!info.tagc)
        {
            info.tagc = info.tag || 'div';
        }
        */
    }
    /* the following code is missing:
    else {
        // Handles the case when info.constructor === Object
        // from the beginning
        // AND
        // info.children isn't an array
        if (info.children.constructor !== Array)
            info.children = [info.children];
    }
    */
EDIT: Some of you seemed to think the fourth conditional is relevant to my problem. The problem is actually that I cannot do the following:
If condition1 Then action1
If !condition1 && condition2 Then action2
If !condition2 && condition3 && regardlessOf(condition1) Then action3
Without using flags (temporary boolean variables).
Basically if condition1 is true, I don't have to test for condition2, and, if condition2 is true, I don't have to test for condition3. But, if condition1 && !condition2, I might have to test for condition3.
Maybe change labels to functions, and gotos to setTimeout(functionname, 0)
For example, instead of:
label1:
    // do something
    goto label2
label2:
    // do something
    goto label1
try something like this:
function label1 () {
    // do something
    setTimeout(label2, 0);
    return; // may be needed if not at the end of function
}
function label2 () {
    // do something
    setTimeout(label1, 0);
    return; // may be needed if not at the end of function
}
(You have to use timeouts because first JavaScript doesn't optimize tail calls (yet) and second because you don't want to block the browser and timeout of 0 puts your callback at the end of the event loop)
Unless my eyes are failing me or I'm missing an obscure side-effect, the first goto-ridden example is equivalent to the following if-else based version (bless 1960's structured programming constructs):
$.fn.hierarchy = function(info, ret) {
    if (info.constructor !== Object) {
        info = {children: info};
        // goto label1; // Illegal JavaScript
        // label1:
        if (info.children.constructor !== Array){
            info.children = [info.children];
        }
    }
    else if (!info.children) {
        info.children = [];
        // goto label2; // Illegal JavaScript
        // label2:
        if (!info.tagc)
        {
            info.tagc = info.tag || 'div';
        }
    }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With