Correct JavaScript IF Else Syntax - javascript

I am updating an existing JavaScript application. Part of this update involves formatting things better and cleaning up code.
Right now this is one of the Functions which uses if() and else statements without all the correct brackets in place... I personbally hate it when people do this shorthand method and even more so when they mix it and use it sometimes and not others. THat is the case in this example code below.
this.setFlags = function() {
if (document.documentElement)
this.dataCode = 3;
else
if (document.body && typeof document.body.scrollTop != 'undefined')
this.dataCode = 2;
else
if (this.e && this.e.pageX != 'undefined')
this.dataCode = 1;
this.initialised = true;
}
I honestly do not know how to correctly add the brackets to this function, below is what I have but I am thinking it might not be correct. Can a JavaScript expert let me know?
this.setFlags = function() {
if (document.documentElement){
this.dataCode = 3;
}else{
if (document.body && typeof document.body.scrollTop != 'undefined'){
this.dataCode = 2;
}else{
if (this.e && this.e.pageX != 'undefined'){
this.dataCode = 1;
}
}
}
this.initialised = true;
}

I share your dislike of unbracketed if/else statements. Your bracketing seems correct to me. However, there's a simpler way that's equivalent:
this.setFlags = function() {
if (document.documentElement) {
this.dataCode = 3;
} else if (document.body && typeof document.body.scrollTop != 'undefined') {
this.dataCode = 2;
} else if (this.e && this.e.pageX != 'undefined') {
this.dataCode = 1;
}
this.initialised = true;
}
As Dave Chen points out in a comment, because of the simplicity and parallelism of the if/else branches—they all assign a value to this.dataCode—you could also use nested ternary operators:
this.setFlags = function() {
this.dataCode = document.documentElement ? 3
: document.body
&& typeof document.body.scrollTop != 'undefined' ? 2
: this.e && this.e.pageX != 'undefined' ? 1
: this.dataCode;
this.initialised = true;
}
The advantage of this is that it is clearer that all the conditions are simply determining which value to assign to this.dataCode. The disadvantage (a big one, in my opinion) is that unless the nested ternary operators are formatted in a careful way (such as what I did here), it's basically impossible to get any sense of what's going on without carefully studying the expression. Unfortunately, most JavaScript code formatters that I'm familiar with do a very poor job of formatting such expressions (or preserving such formatting). (Interestingly, several Perl formatters that I've used do a wonderful job of this. But this isn't Perl.)

It's correct but you can make it neater:
this.setFlags = function() {
if (document.documentElement) {
this.dataCode = 3;
} else if (document.body && typeof document.body.scrollTop != 'undefined') {
this.dataCode = 2;
} else if (this.e && this.e.pageX != 'undefined') {
this.dataCode = 1;
}
this.initialized = true;
};
oh this is already posted

Related

if statements being skipped even when both expressions are true

I have a webpage that populates a table with arrays. It has a doClick function so that when a user clicks on a cell it passes the row and column of the cell to the function. Example cell: onclick="doClick(0,1)"
function doClick(row, col)
{
var top = row -1;
var bottom = row +1;
var left = col -1;
var right = col +1;
var swapped = false;
if ((top != -1) && (cells[top][col].innerHTML = ""))
{
cells[top][col].innerHTML = cells[row][col].innerHTML;
cells[row][col].innerHTML = "";
swapped = true;
}
else if ((right != 4) && (cells[row][right].innerHTML = ""))
{
cells[row][right].innerHTML = cells[row][col].innerHTML ;
cells[row][col].innerHTML = "";
swapped = true;
}
else if ((bottom != 4) && (cells[bottom][col].innerHTML = ""))
{
cells[bottom][col].innerHTML = cells[row][col].innerHTML;
cells[row][col].innerHTML = "";
swapped = true;
}
else if ((left != -1) && (cells[row][left].inn = ""))
{
cells[row][lef].innerHTML = cells[row][col].innerHTML;
cells[row][col].innerHTML = "";
swapped = true;
}
else
{
alert("Illegal Move.");
}
. The problem is, even if both if expressions are true, the if statement is being skipped and it's falling through to the else statement. I've desk checked it and run it through the developer tools and checked values. A statement that was true on both expressions was skipped. Any suggestions?
cells[row][right].innerHTML = ""
is wrong. You are missing the double (triple) =.
The correct way should be...
cells[row][right].innerHTML === ""
It looks like maybe there are a few typos or misconceptions in your code.
A quick note about Conditions in an IF statement
A statement like (cells[top][col].innerHTML = "") as a condition will always return true as this is setting cells[top][col].innerHTML as "" or at least instantiating the variable. So, the proper condition to test absolutely true or false would be (cells[top][col].innerHTML === ""). However, you can get away with not even doing that and simply replace (cells[top][col].innerHTML = "") with cells[top][col].innerHTML. You may run into some other issues though is the variable is not instantiated already, either way. I would wrap the latter logic in an IF statement to check if cells[top][col].innerHTML is even instantiated.
To fix this, check out the following modifications I have made to your code.
function doClick(row, col)
{
var top = row -1;
var bottom = row +1;
var left = col -1;
var right = col +1;
var swapped = false;
if(typeof cells[top][col].innerHTML !== 'undefined' $$ cells[top][col].innerHTML !== null)
{
if ((top != -1) && cells[top][col].innerHTML !== '')
{
cells[top][col].innerHTML = cells[row][col].innerHTML;
cells[row][col].innerHTML = "";
swapped = true;
}
else if ((right != 4) && cells[row][right].innerHTML !== '')
{
cells[row][right].innerHTML = cells[row][col].innerHTML ;
cells[row][col].innerHTML = "";
swapped = true;
}
else if ((bottom != 4) && (cells[bottom][col].innerHTML))
{
cells[bottom][col].innerHTML = cells[row][col].innerHTML;
cells[row][col].innerHTML = "";
swapped = true;
}
else
{
alert("Illegal Move.");
}
}
else if (typeof cells[row][left].inn !== 'undefined' && (left != -1) && cells[row][left].inn !== '')
{
cells[row][lef].innerHTML = cells[row][col].innerHTML;
cells[row][col].innerHTML = "";
swapped = true;
}
else
{
alert("Illegal Move.");
}
}
An example working to demonstrate the above code
var testVar1 = '';
var testVar2 = 'Hello';
// var testVar3; <- Left this un-instantiated to test existance
// Testing if a var is empty but exists
if(typeof testVar1 !== 'undefined' && testVar1 !== null){
if(testVar1 !== ''){
alert('testVar1 has a value!');
}{
alert('testVar1 does not have a value!');
}
}
// Testing if a var is empty but exists
if(typeof testVar2 !== 'undefined' && testVar2 !== null){
if(testVar2 !== ''){
if(testVar2 === 'Hello'){
alert('testVar2 has a value! Value: ' + testVar2);
}{
alert('testVar2 has a value but it is not the one we expected.');
}
}{
alert('testVar2 does not have a value!');
}
}
// Test existance
if(typeof testVar3 !== 'undefined' && testVar3 !== null){
alert('testVar3 exists!');
}else{
alert('testVar3 does not exist!');
}

Comma separated expression simplify

I'm trying to simplify code below
if (a ||
node != r._start ||
(start = n + r._startOff, a = true),
a && node == r._end) { .... }
Can someone help me to separate this if condition to simplify form? (without commas)?
The code in the if condition will always run... this is the simplify version:
var doYourStuff = false;
if (a || node != r._start) {
doYourStuff = true;
} else {
start = n + r._startOff;
a = true;
if (node == r._end) {
doYourStuff = true;
}
}
if (doYourStuff) {
// ... do your stuff
}

javascript binary tree, check whether it is a mirror of itself

I learn javascript recently, I don't know why the code I wrote is wrong. Here is the quesion:Given a binary tree, check whether it is a mirror of itself.
var isSymmetric = function(root) {
if(root === null) return true;
function isSymmetric(leftNode, rightNode){
if(leftNode === null && rightNode === null) return true;
if(leftNode === null || rightNode === null) return false;
return (leftNode.val == rightNode.val) && isSymmetric(leftNode.left, rightNode.right) && isSymmetric(leftNode.right, rightNode.left);
}
isSymmetric(root.left, root.right);
};
when the input is 1, the result is "undefined". This algorithm is transformed from my Java code. Please kindly inform me where I get wrong.
var isSymmetric = function(root) {
if (root === null) return true;
function isSymmetric(leftNode, rightNode) {
if (leftNode === null && rightNode === null) return true;
if (leftNode === null || rightNode === null) return false;
return (leftNode.val == rightNode.val) && isSymmetric(leftNode.left, rightNode.right) && isSymmetric(leftNode.right, rightNode.left);
}
return isSymmetric(root.left, root.right);
};
you need to return the result of isSymmetric as shown above
personally, I wouldn't have the outer and inner functions have the same name, it looks confusing to my old eyes :p

missing parenthesis error in javascript

I am using this function:
function sel_test(e) {
//alert(e.length-1);
var splitdata = e.split("d");
var newstr = e.substring(0,e.length-1);
dropcall = 1;
nodes = newstr.split(';');
o = 0;
if (nodes[0] == '1') o = nodes.shift();
for (i=0;i<nodes.length;i++) {
e = nodes[i];
var ul = document.getElementById(e);
if (icons) var img = document.getElementById(e+'i');
if (ul) {
if (((ul == 'none') AND (ul.style.display == 'none')) OR (ul.style.display == '')) {
ul.style.display = 'block';
} else if (!o) {
ul.style.display = 'none';
}
}
}
javascript is giving me an error of missing parenthesis:
if (((ul == 'none') AND (ul.style.display == 'none')) OR (ul.style.display == '')) {
what this the correct way of doing this.
You should be using && and || instead of AND and OR.
Shouldn't you?
Try this:
if (((ul == 'none') && (ul.style.display == 'none')) || (ul.style.display == ''))
JavaScript has an AND operator, but it isn't the word AND, it is && (also &, for a bitwise and). Similarly, rather than OR you want || (or | for bitwise).
Note that your ul variable will never be equal to the string 'none' - the return from document.getElementById(e) will always be either the matching DOM element, or null if no element has the supplied id.
Further reading: Logical Operators (and you should read it, because && and || don't always return true or false and MDN explains this).
You are also missing the closing right squiggly for the function.

If element exist then check?

The code does work below when the access to the webpage, it automatically hide #OrderDeliveryAddress div. But I am wondering is this correct way doing it?
Is there a way to check if .selectAddressList div/class exist first and then check the value?
$(document).ready(function() {
if ($(".selectAddressList").val() == "selectAddressBook") {
$("#OrderDeliveryAddress").hide();
}
});
Personally I would use:
if ($(".selectAddressList").length > 0)
This checks if the jQuery object has any items, in other words if anything matched the selector you passed in.
if($(".selectAddressList").length > 0)
At a second glance though, you're using a class selector for this - do you have multiple items using this class on the page? If so, you might run into conflicts there as you're checking the .val() of it/them. If not, you might consider using element id as opposed to class.
You could just say:
if ($(".selectAddressList").length)
since 0 would mean false in this case and everything else would evaluate to true.
I answered this same question with the following plugin here. Please visit answer for full details on creating of plugin.
The following plugin would allow you to use a callback feature (staying inline with jQuery style markup) if the element exist. So for your example, you might do something like:
$(".selectAddressList").exist(function() { // with NO PARAM, will ONLY fire if element exist
/* DO WORK */
}) // notice, this maintains "chainability", so you could make more calls on this element
Plugin
(function($) {
if (!$.exist) {
$.extend({
exist: function() {
var ele, cbmExist, cbmNotExist;
if (arguments.length) {
for (x in arguments) {
switch (typeof arguments[x]) {
case 'function':
if (typeof cbmExist == "undefined") cbmExist = arguments[x];
else cbmNotExist = arguments[x];
break;
case 'object':
if (arguments[x] instanceof jQuery) ele = arguments[x];
else {
var obj = arguments[x];
for (y in obj) {
if (typeof obj[y] == 'function') {
if (typeof cbmExist == "undefined") cbmExist = obj[y];
else cbmNotExist = obj[y];
}
if (typeof obj[y] == 'object' && obj[y] instanceof jQuery) ele = obj[y];
if (typeof obj[y] == 'string') ele = $(obj[y]);
}
}
break;
case 'string':
ele = $(arguments[x]);
break;
}
}
}
if (typeof cbmExist == 'function') { // has at least one Callback Method
var exist = ele.length > 0 ? true : false; // strict setting of boolean
if (exist) { // Elements do exist
return ele.each(function(i) { cbmExist.apply(this, [exist, ele, i]); });
}
else if (typeof cbmNotExist == 'function') {
cbmNotExist.apply(ele, [exist, ele]);
return ele;
}
else {
if (ele.length <= 1) return ele.length > 0 ? true : false;
else return ele.length;
}
}
else { // has NO callback method, thus return if exist or not based on element existant length
if (ele.length <= 1) return ele.length > 0 ? true : false; // strict return of boolean
else return ele.length; // return actual length for how many of this element exist
}
return false; // only hits if something errored!
}
});
$.fn.extend({
exist: function() {
var args = [$(this)];
if (arguments.length) for (x in arguments) args.push(arguments[x]);
return $.exist.apply($, args);
}
});
}
})(jQuery);
jsFiddle

Categories

Resources