PDA

View Full Version : IF statement with detecting undefined functions

StealthRT
12-14-2007, 01:58 AM
Hey all i am in need of finding a way to make this code work..

I have a fuction called "bob" with variables a,b,c,d,e,f,g,h. I need to find a way to see if each value has anything in it or if its undefined.

Here is my code

<script type="text/javascript">
function bob(a,b,c,d,e,f,g,h) {
var withBreaks = "<br />"

if (d == "undefined")
{
d == ""
}
MOOdalBox.open("fishsite.html", "You need to correct the following before continuing:" + withBreaks + a + withBreaks + b + withBreaks + c + withBreaks + d + withBreaks + e + withBreaks + f + withBreaks + g + withBreaks + h, "750 100");
}
</script>

<p><a href="#" onclick="bob('Test 1','test 2','test 3');">tester</a></p>

As you can tell in my example that d,e,f,g,h will return "undefined" since i dont have anything for it in the link... however, it doesnt seem to set d = ""... it still says undefined when the box loads.

What am i doing incorrect?
David

rnd me
12-14-2007, 02:06 AM
one easy way:
if you want the undefined to be blanks (as above), this should do that

a=a||""
b=b||""
c=c||""
d=d||""
e=e||""
f=f||""
g=g||""

StealthRT
12-14-2007, 02:09 AM
Thanks for the reply rnd_me but that doesnt seem to work:

if (d == "undefined")
{
d=d||""
}

Unless, yet again, i have it mixed up..

David

StealthRT
12-14-2007, 02:13 AM
Err.. i guess u meant it like this?

if (d=d||"")
{
d=""
}

David

StealthRT
12-14-2007, 02:20 AM
That doesnt seem to work either becuase it thinks even with the test 1, test 2, etc its undefined no matter what....

David

Trinithis
12-14-2007, 02:31 AM
You want

if(d === undefined)

Triple equal signs and no quotes.

StealthRT
12-14-2007, 02:43 AM
Hey thanks Trinithis! :) it works!

Final code:

<script type="text/javascript">
function bob(a,b,c,d,e,f,g,h) {
var theSaying = ""

if (h === undefined){h=""}else{theSaying = "<br />" + h + theSaying}
if (g === undefined){g=""}else{theSaying = "<br />" + g + theSaying}
if (f === undefined){f=""}else{theSaying = "<br />" + f + theSaying}
if (e === undefined){e=""}else{theSaying = "<br />" + e + theSaying}
if (d === undefined){d=""}else{theSaying = "<br />" + d + theSaying}
if (c === undefined){c=""}else{theSaying = "<br />" + c + theSaying}
if (b === undefined){b=""}else{theSaying = "<br />" + b + theSaying}
if (a === undefined){a=""}else{theSaying = "<br />" + a + theSaying}
MOOdalBox.open("fishsite.html", "You need to correct the following before continuing:" + theSaying, "750 100");
}
</script>

Thanks again!
David

rnd me
12-14-2007, 02:56 AM
unknown number of args could be easily done like:

var a= arguments;
for(var i=0;i<a.length;i++){ if (a[i]){theSaying = "<br />" + a[i] + theSaying} }

(i personally don't like repetitive coding...)

Trinithis
12-14-2007, 03:08 AM
Eewww! :D

rnd me beat me to it

How about . . .

if(!Array.prototype.reduce) {
Array.prototype.reduce = function(f /*, initial*/) {
var i = 0, r = arguments.length > 1
? arguments[1]
: this[i++];
for(var n = this.length; i < n; ++i)
r = f.call(null, r, this[i], i, this);
return r;
};
}

function bob(a, b, c, d, e, f, g, h) {
var theSaying = [a, b, c, d, e, f, g, h].reduce(function(s, v) {
return v === undefined
? s
: s + "<br \/>" + v;
}, "");
MOOdalBox.open("fishsite.html", "You need to correct the following before continuing:" + theSaying, "750 100");
}

Or probably even better

function bob(/*args*/) {
var theSaying = Array.prototype.reduce.call(arguments, function(s, v) {
return s + "<br \/>" + v;
}, "");
MOOdalBox.open("fishsite.html", "You need to correct the following before continuing:" + theSaying, "750 100");
}

StealthRT
12-14-2007, 03:12 AM
Thanks rnd me & Trinithis but non of those codes seem to work.. it never pops up the box anymore after changing the code. But the long "ewww" code does work, however...

David

Trinithis
12-14-2007, 03:17 AM
Hrmmm. This is the exact code for my test.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
</head>

<body><div>
<script type="text/javascript">

if(!Array.prototype.reduce) {
Array.prototype.reduce = function(f /*, initial*/) {
var i = 0, r = arguments.length > 1
? arguments[1]
: this[i++];
for(var n = this.length; i < n; ++i)
r = f.call(null, r, this[i], i, this);
return r;
};
}

function bob(/*args*/) {
var theSaying = Array.prototype.reduce.call(arguments, function(s, v) {
return s + "<br \/>" + v;
}, "");
alert(theSaying);
}

bob(8, 2);

</script>
</div>
</body>
</html>

Should alert "<br />8<br />2"

Tested in Fx2 and IE6

rnd me
12-14-2007, 03:31 AM
if(!Array.prototype.reduce) {
Array.prototype.reduce = function(f /*, initial*/) {
var i = 0, r = arguments.length > 1
? arguments[1]
: this[i++];
for(var n = this.length; i < n; ++i)
r = f.call(null, r, this[i], i, this);
return r;
};
}

warning: this could be unstable code!

when i was coding forEach, map, and filter equivalents for 2nd-tier browsers, i realized that special attention was needed to the variable name used in my replacement prototypes.

In your code, if someone passes a function that changes or reads a var named i, n, r, or f, it can possibly clash with the prototype's version.

this is especially true when using "replacement protos" in a nested fashion.
i recommend trying to avoid such common names in the functions which need to be called by others.
i don't think is a supoer-huge issue with this, but it could pop-up, and it would be a major PITA to debug if it did.

this can lead to infinite loops (if i or n was changed), to less serious, but still undesirable effects.

one good way around this would be to use a unique named object as variable container.
then all the inners are ob.i, ob.r, etc.
don't use ob either, be creative.

i am not saying the code posted will not work, but with an unknown function being passed, possibly containing stuff like window.xxx, with, eval, or new Function(), it is better to play it safe.
this is one instance where JavaScript's closure is a bad thing.

EDIT:
this doesn't seem to be nearly as big a problem as i thought.
i should examine the diff between apply and call more in depth.
for some reason, this code seems to be better than my earlier replacements.

StealthRT
12-14-2007, 03:40 AM
Yeah still cant get it to work... however mine is fine for what i need to do with it since ill be the only one changing the values. :)

David

rnd me
12-14-2007, 03:50 AM
Thanks rnd me & Trinithis but non of those codes seem to work.. it never pops up the box anymore after changing the code. But the long "ewww" code does work, however...

David

whoops!
not following my own advice about variable names!

function bob(a,b,c,d,e,f,g,h) {
var theSaying = ""
var a2= arguments;
for(var i=0;i<a2.length;i++){ if (a2[i]){theSaying = "<br />" + a2[i] + theSaying} }
alert(theSaying) //i dont have mootools...
//MOOdalBox.open("fishsite.html", "You need to correct the following before continuing:" + theSaying, "750 100");
}

bob("dan", "fred", "jane")

tested ff2

Trinithis
12-14-2007, 04:03 AM
@rnd me:

I don't see how any of that is an issue as long as the local variables declared within reduce (or any other function) can be changed by a callback as long as the variable is declared with the keyword var or is a formal argument.

Here's some test code to state my point. In all, I think it's a matter of scope and not closures. Unless I've missed something, I'm 100&#37; positive that reduce does not create a closure. The reduce function only can see it's own reduce scope and the global window scope. Even though it calls other functions, those functions are defined in different scopes. So the only thing you might worry about would be the callback changing a global variable.

By all means, if I'm wrong, could you show me an example?

(In the example, the (modified) reduce function has an added junk argument and alerts n and junk after the callbacks are done. They stay "normal" in my two tests.)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
</head>
<body><div>
<script type="text/javascript">

Array.prototype.reduce = function(f, junk) {
var i = 0, r = arguments.length > 1
? arguments[1]
: this[i++];
for(var n = this.length; i < n; ++i)
r = f.call(null, r, this[i], i, this);
alert(n + "\n" + junk);
return r;
};

function f1() {
i = Number.POSITIVE_INFINITY;
junk = "junkChanged!"
}

function test() {
var n = 0, junk = "junkChanged!";
var f2 = function() {
n = 0;
};
[1, 2, 3].reduce(f2, "not junk");
}

[1, 2, 3].reduce(f1, "not junk");
test();

</script>
</div>
</body>
</html>

StealthRT
12-14-2007, 04:05 AM
Very nice rnd me, it worked! :)

Quick question... I'm using some code thats called coda-slider.. http://www.ndoherty.com/demos/coda-slider/1.1.1/#1

And the way u move from DIV to DIV is having a link like so:

<a href="#2" class="cross-link">Next</a></p>

That code above would goto the DIV2. Now how can i put that link inside this code of mine to fire it off?

function Step1()
{
if (Checkit1())
{
**move to DIV2**
}
else
{
return false;
}
}

David