PDF In-Depth

Make It Easy on Yourself

September 20, 2001

Advertisement
Advertisement
 

One of the things that makes JavaScript such a powerful, easy-to-use language (compared to procedural C, say, which shares many of the same syntactical constructs) is its relaxed data-typing: that is, its ability to let you use strings and numbers more-or-less interchangeably, without any need to perform explicit typecasts or adhere to type rules. In JavaScript, a number is a number in numeric contexts and a string in string contexts. That is, you can do things like:


var n = new String('30');  // create string, "30"

n = n * 2;  // 'n' is now 60

n += "3"; // 'n' is now 603

n = n.substr(0,2); // 'n' is now 60 again  

All of this, without generating an error. In any other language, the Type Police would have you in jail in a nanosecond!

But relaxed typing is a double-edged sword. Sometimes, you NEED a number to be a number, not a string. For example, suppose you have a function called Sum(), which sums two values:

function Sum(n,m) {
  return n + m;
}

Unfortunately, the function doesn't "know" whether the arguments being passed are numeric, or strings. If either one is a string, the return value will be a string! Thus, if 'n' equals the number 50, but 'm' equals the string '2', the value returned by Sum() will be the string '502', which may or may not be what you expected.

There are several ways of dealing with this. A not-very-elegant way would be to check the types of the incoming parameters with JavaScript's typeof() function, which will return 'string' for a String object or 'number' for a number, and perform any necessary conversions of non-numeric arguments. A more sensible way to proceed is just to force the conversion to a number by multiplying each argument value by one:

function Sum(n,m) {
  return (1*n + 1*m);
}

Multiplying a string by one (or adding zero to it) is a very old JavaScript hacker's trick for performing explicit type conversion. Multiplying a string by unity or adding zero to it puts the string in a numeric context, which puts the JavaScript runtime interpreter on notice that the expression in question needs to evaluate to a numeric result. The only downside to this sort of approach is poor readability. Multiplying variables by unity looks strange and "junks up" your code to a certain extent. A more readble approach is shown below:

function Sum(n,m) {
  return (Number(n) + Number(m));
}

You can also use String() to convert numbers to strings, in place. If the Number() and String() methods seem strangely familiar (yet odd in this context), recall that core JavaScript provides for the use of constructor functions by these names. To construct a string or number, you can do:

var s = new String("Hello World!");

var n = new Number(9);

The same methods, minus the "new" keyword, can be used to force an explicit "typecast" on the fly. I've found that this can be incredibly handy when you've got a situation in which you can't remember whether you're dealing with a number or a string (but you know you need one or the other). A good rule of thumb is this: When you KNOW you need a number, explicitly coerce every value to a numeric value. Otherwise, the day will come when you (or your user) will see the famous NaN (Not-a-Number) error in the JavaScript console at runtime, indicating that your code tried to use a string as a number, and failed. (It happens!)

Another Way to Make Strings

Don't forget that on those occasions when you want to be certain that you're dealing with a string, you can force ANY JavaScript data type or object to become a string by applying the toString() method, which is available at all times to all data types and objects. (You can even apply this method to functions. Try it!)

Of course, once you've made something into a string, either with the ubiquitous toString() method or some other way, you then have all the power and utility of the String class methods available to you. This means, for example, that you can truncate decimal numbers to a given number of digits quite easily:

var pi = Math.PI;  // pi is now 3.14159265358979

pi = pi.toString().substr(0,7);  // now it's 3.14159
pi = pi.toString().substr(0,4);  // now 3.14

The substr() method takes a starting offset and a length value. It extracts a substring from the parent object, starting at the offset given and continuing for "length" characters.

Dates as Numbers

The Date object is a good example of how JavaScript entities can take on numeric attributes or string attributes depending on the context and circumstance. Try this exercise: Create a button using Acrobat's form tool and link this line of JavaScript to the mouse-up event:

app.alert(new Date);

When you click the button (causing the script to fire), you will see an alert dialog bearing a message similar to:

    Tue Feb 22 13:15:08 2000

Obviously, in this context, a Date object is being treated as a string. But if you multiply the Date object by 1.0, shown below, you get a much different result:

   app.alert(new Date * 1.0); // alert says: 951243107745

   (Note that parens are optional on Date.)

The long number shown in numeric context is the Date's raw value: the number of milliseconds since January 1, 1970. (Just multiplying it by one coerces it to a numeric value.) This can obviously be handy if you need to set a "time out" value in a script. Suppose that you want to set a form up so that after a certain date (say July 4, 2000), a given field displays with a background color of red.

var deadline = new Date("Jul 4 2000");

if (new Date() - deadline > 0)
this.getField('fieldname').bgColor = ['RGB',1,0,0];

The numeric context in the condition check forces the dates to become numbers: raw millisecond values. Since a future date is a bigger value than a more recent date, the subtraction produces a negative number until the deadline passes. After the deadline has passed, the difference is positive.

Dates As Strings

But once you understand that an object can be both a number and string (depending on context), it's easy to deal with dates as strings. For example, if you want to show the current date in a form field called "current_date", but you don't want to display the day of the week nor the hours:min:sec information returned in a call to new Date(), use the string method, substr(), to extract just the info you want to display:

var date = new Date();

this.getField('current_date').value =
        date.toString().substr(4,7)+
        date.toString().substr(21,4);

The display will be something like: "Feb 29 2000".

Characters as Numbers (and Vice Versa)

Finally, let's consider how to convert a character (a letter) to an ASCII value (a number), or vice versa.

To get the numerical (ASCII) value of a character code in JavaScript, you have to use the charCodeAt() method of the String class.

var asciiValue = "e".charCodeAt(0); // asciiValue is 101 

Notice here, I resort to the useful trick of applying string methods to a single character treated as a string literal. (Anything between quotation marks qualifies as a string object.) To get a character value from a raw number, you use the static String method, fromCharCode():

var str = new String;  // create empty string

str += String.fromCharCode(101); // add 'e'

Since fromCharCode() is a static method, you call it using the class name ("String") as the parent object.

One caveat applies here. In Acrobat 4.xx (on my Mac, at least), the charCodeAt() method returns a negative number for ASCII values greater than 127. This is contrary to the behavior of core JavaScript in other environments (such as in Netscape browsers), where charCodeAt() returns only positive numbers. I'm told this "feature" may be corrected in the next release of Acrobat, which will use the JavaScript 1.4 engine. Until then, remember to watch out for "negative ASCII values" when using charCodeAt() in Acrobat.

PDF In-Depth Free Product Trials Ubiquitous PDF

Debenu Quick PDF Library

Get products to market faster with this amazing PDF developer SDK. Over 900 functions and an equally...

Download free demo

Back to the past, 15 years ago! Open Publish 2002

Looking back to 2002, it's amazing how much of the prediction became a reality. Take a read and see what you think!

September 14, 2017
Platinum Sponsor





Search Planet PDF
more searching options...
Planet PDF Newsletter
Most Popular Articles
Featured Product

Debenu PDF Aerialist

The ultimate plug-in for Adobe Acrobat. Advanced splitting, merging, stamping, bookmarking, and link control. Take Acrobat to the next level.

Features

Adding a PDF Stamp Comment

OK, so you want to stamp your document. Maybe you need to give reviewers some advice about the document's status or sensitivity. This tip from author Ted Padova demonstrates how to add stamps with the Stamp Tool along with related comments.