Checking for an empty string

Its interesting to look through a repository and see what different methods people use to test for an empty string. Some projects standardize on 1 method, while other projects arnt so consistent.

In this article i'll go through the different methods for testing an empty string in Siebel and look at its pros and cons.

Lets start with our empty string;

var sEmpty = "";


[Method 1]

if (sEmpty == "")
;


This method is used in the Prototype library, and is the most common way of testing for an empty string, and looks the most natural, but it has a flaw.

You may not see any immediate effects of using this method, but if sEmpty is accidentily set to 0, then the expression will evaluate to true. Why does this happen?

If string is compared to a number, the string will be converted to a number implicitly by the engine, before the comparison is made. So the "" will be converted to 0 and compared with 0, which returns true.

[Method 2]

if (sEmpty.length == 0)
;


This is another common way of testing for an empty string, its not as natural as method 1, but is still readable and works well in a strict circumstances.

Strict circumstances? If sEmpty is only declared and not initialized as a string eg. var sEmpty, or declared and not assigned a value, then this method will raise an error.

If people forget to initialize their variables, or the conditions were not met to assign a value to the variable, then this is another potential problem.

Have a look at the following example:

var sErrorMsg;
try{
//do something
} catch(e){
sErrorMsg = e.toString();
} finally {
if (sErrorMsg.length>0)
TheApplication().RaiseErrorText(sErrorMsg);
}


sErrorMsg will only get populated if there is an error, in normal circumstances this will raise an error, of course this would not pass unit testing, but there are times when this problem is less obvious.

To avoid this problem initialize your variables.

[Method 3]

if (sEmpty === "")
;


This method is an improvement on method 1 (note the triple equal sign), the === forces the engine to do a strict compare of the value as well as the type of the object. So if we try to compare "" with 0, the engine will see the mis-match in object types, and return a no match.
eg.

if("0"==0);//returns true;
if("0"===0);//returns false;


In theory, this method is faster than the normal == compare, because the engine dosnt have to perform a type conversion.

If we forget to initialize our sEmpty variable again, or assign it a null, then it would also return false, which in a strict sense is correct. An empty string does not technically equal a null or undefined object, but logically it dosnt contain a value and should return empty.

[Method 4]

if (!sEmpty)
;


This last method is more relaxed. What this does is check if sEmpty has a value (or if the value is true) and performs a NOT. So wether your variable is declared like

var sEmpty = "" //or
var sEmpty //or
var sEmpty = null;


This will return false, meaning our variable is empty or has no value. The problem with this method is the same as Method 1, if our sEmpty string is set to the number 0, then it will return empty.

[So which method should you use?]

Method 1 - if (sEmpty == "")
Method 4 - if (!sEmpty)
These methods have a flaw but you can use it with a bit more work

Modified Method 1 a - if (sEmpty==""&&sEmpty!==0)
Kinda ugly, but it works. Method 2,3 are more elegant alternatives.

Modified Method 1 b - if (ToString(sEmpty)=="")
Another variation to get around the same problem. We apply the eScript ToString function to make sure what we have is a string, before doing the compare.

Modified Method 4 - if (!sEmpty&&sEmpty!==0)
This method is good for relaxed comparisons which caters for null and undefined (un-initialized) strings as well.

Methods 2 - if (sEmpty.length == 0)
Methods 3 - if (sEmpty === "")
These methods are good if you need strict comparisons and practice good variable initiation.

[How about creating a String prototype?]

This sounds like a good idea, because we can standardize the implementation and use it system wide. The only caveat with using this as a prototype is that it will only work on string objects! Try it on a number, null, undefined and you will will get an error, because our method is not defined on those object types.

Alternatively, we *could* attach this to the global object prototype, but this isnt a scalable solution. The better alternative is to make this as part of a script library and make use of dynamic typing, then call it like a function instead of a prototype method. (ala ABS Framework)

Who knew that checking for an empty string was so much hassle? If you dont have a script library, you can stick to checking the object length or the ===, but keep in the mind the limitations.

Checking for an empty (Strong Typed) String


Reactions:

4 comments:

  1. method 5
    if (sEmpty == null)

    ReplyDelete
  2. This dosnt pass the empty string test
    var sEmpty="";

    I'm interested to see if there are any other methods

    ReplyDelete
  3. I'm away from an instance of Tools at the moment so can't check this but wonder if strong typing the variable being checked would have any impact? Eg.

    var sMyString1 = "";
    var sMyString2:String = "";

    Would 1 and 2 behave the same?

    ReplyDelete
  4. Hi Matt, this is an interesting point. Both methods behave totally different. I'll cover this in a followup article.

    ReplyDelete

Comments are open to all, please make it constructive.