All about types in Javascript - The basics
Javascript is a loosely typed language. That means a variable x may now hold a number, two lines down a string and another ten lines down an HTML element. What might be confusing is that Javascript often converts types automatically. The rules behind automatic type convertion sometimes are - well, surprisingly abnormal. Did you know that
evaluates to true and why?
Programmers from other languages such as Java often find dynamic typing challenging, and therefore try to twist Javascript to help avoid typing problems like that:
function isNumber(obj) { return typeof(obj) == 'number'; }
function isBoolean(obj) { return typeof(obj) == 'boolean'; }
function isFunction(obj) { return typeof(obj) == 'function'; }
function isObject(obj) { return typeof(obj) == 'object' || isFunction(obj); }
function isArray(obj) { return isObject(obj) && obj instanceof Array; }
function isDate(obj) { return isObject(obj) && obj instanceof Date; }
function isError(obj) { return isObject(obj) && obj instanceof Error; }
function isUndefined(obj) { return typeof(obj) == 'undefined'; }
function isNull(obj) { return obj === null; }
function isNone(obj) { return isUndefined(obj) || isNull(obj); }
function isSet(obj) { return !isNone(obj); }
function isTrue(obj) { return isSet(obj) && !!obj; }
function isFalse(obj) { return isSet(obj) && !obj; }
That's a real life example. I think it's a pity. Though it might help in the first hand, it hinders the developer to truely master the language and the benefits that come with dynamic typing.
There are four important aspects involved with dynamic typing, which I will cover in a series of articles.
The first (the one you are reading) includes the basics: What types does Javascript have and what are the general rules of type convertion.
The second is about automatic type convertion. When and how does automatic type convertion occur?
Sometimes you need to explicitly convert a type to another. The third part will cover the most suitable ways to do so.
Finally we consider ways of type detection. For some types that's easy, for others it spells disaster.
Types in Javascript - The basics
There are five primitive types in Javascript and there are objects. The primitive types are undefined, null, boolean, number, and string. Objects include (but are not limited to) Array, Function, and Date.
The type undefined has exactly one value: undefined. It is used when a variable has not been assigned a value.
The type null has exactly one value as well: null. It is mostly used to represent a non-existent reference.
// b is null
We slowly increase the number of values. The type boolean has to values: true and false.
var d = !c; // false
Now there is a huge step in values. There are 18437736874454810627 possible values for the number type. Numbers in Javascript are represented by double-precision 64-bits according to IEEE 754.
Take a moment and think about it. You know what I mean? There are no integers in javascript! Though integers between -231 and 231 - 1 are represented exactly in Javascript they still are floating point numbers, not integers.
In addition, there are three special values: NaN, which stands for "not a number" (though still it is a number), positive Infinity and negative Infinity.
var f = e / 0; // f now is Infinity
As a footnote I want to add that there are two zeros in Javascript. You rarely will encounter a situation where that matters. I have yet to make that experience.
A string in Javascript is a primitive in contrast to e.g. Java. Thus you compare two strings by the equality operator ===, you do not need an equals function. Every character is represented by a 16-bit unsigned integer value, therefore unicode characters with codepoint 65536 and above cannot be used in Javascript.
Everything else is an object. For type convertion it does not matter which kind of an object you have. Mostly. I will cover the details in the coming sections.
Conversion
Some statements in javascript and many operators expect values of a specific type. The if statement for example expects a boolean and if you call it with any other type it has to be converted.
Conversion to boolean
Convertion to boolean is quite easy. Null and undefined are converted to false, any object is converted to true. Numbers are converted to true except for 0 and NaN which are converted to false. The empty string is converted to false, any other to true.
value | to boolean | comment |
---|---|---|
undefined | false | |
null | false | |
0 | false | |
NaN | false | |
any other number | true | including Infinity |
"" | false | |
any other string | true | |
Object | true |
Conversion to number
Convertion to number is a bit more complex, especially when dealing with strings and objects. Simply said, if by removing the quotes of a string you get a number this is the number the string is converted to. Otherwise it is converted to NaN. The boolean value of true is converted to 1, false to 0. Null is converted to 0 while undefined is converted to NaN.
value | to number | comment |
---|---|---|
undefined | NaN | |
null | 0 | |
true | 1 | |
false | 0 | |
"" | 0 | |
"123" | 123 | |
"0xff" | 255 | hexadecimal |
"061" | 53 | octal |
"123,4" | NaN | this differs from parseInt/parseFloat |
"what" | NaN |
I did not cover conversion of an object to a number yet. Well, why would you want to convert an object to a number? Dates, that is. To compare Dates and to calculate the difference between two Dates you need to convert them to numbers. Since a Date is internally stored by the number of milliseconds since January 1, 1970, that value is the number a Date is converted to.
Technically, conversion of an object is is done by two steps: First the object's valueOf method is called (probably inherited from Object.prototype) and if that returns a primitive type, it is converted as noted above. Otherwise the object's toString method is called, the resulting string then is converted to a number.
This may lead to interesting results. When dealing with arrays, an array is converted to a string by converting the elements to string, seperating each element by a comma.
[2].toString(); // "2"
[1,2,3].toString(); // "1,2,3"
Now if you convert an array to a number, the result surprisingly depends heavily on the array itself. Since the valueOf method of an array returns the array itself, the toString method is called with the results above.
Number([2]); // 2
Number([1,2,3]); // NaN
As another footnote I want to say I have never ever had the need to convert an array to a number.
Conversion to string
To convert a primitive to string, simply said, enclose the value with quotes. When converting numbers to string, take a decimal representation of that number. When converting an object to string, call the object's toString method.
value | to string | comment |
---|---|---|
undefined | "undefined" | |
null | "null" | |
true | "true" | |
false | "false" | |
NaNl | "NaN" | |
0 | "0" | |
1 | "1" | |
Object | result of the object's toString method |
Summary
That covers the basics of types in Javascript and the general rules on conversion.
I know I have been quite inprecise when dealing with objects. The standard talks about methods called [[DefaultValue]] having an optional hint, of [[ToPrimitive]] and something called [[ToInt32]] and [[ToUint32]] and so on. I thought this too technical for the average advanced developper, so I skipped the details.
For further reading I recommend either chapter 8 and 9 of ECMA-262 (if you don't mind technical stuff) or chapter 3 of David Flanagan's JavaScript - The Definitive Guide, 5th Edition.
- Login to post comments
Comments
basic rules for code readability and the if statement | unit (not verified) - Mon, 08/01/2011 - 14:30
[...] you only want to check it the value of name is set. Many languages like Javascript (read the all about types by Matthias Reuter) can convert the value directly into a truthy value (read more on The Elements [...]