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 goto
s 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 goto
s. 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