united-coders.com

  • Authors
    • Christian Harms
    • Nico Heid
  • Datenschutz
  • Impressum
Home » All about types in Javascript – Automatic type conversion

All about types in Javascript – Automatic type conversion

Posted on May 25, 2009 by Matthias Reuter Posted in Uncategorized

This is the second part of a series “All about types” in Javascript.

  1. The basics – types and general rules of conversion
  2. Automatic type conversion
  3. Explicit type conversion
  4. Type detection

Automatic type conversion

You have seen it before:

var element = document.getElementById("someId");
if (element) {
  // do something
}

That’s an automatic type conversion. The if-statement expects a boolean value, and if the given expression does not return one, the result is converted. document.getElementById either returns an object or null. Null is converted to false, any object to true. That’s why constructions as the above work.

In general, every time an operator or a statement expects a value of a certain type but a different type is given, automatic type conversion occurs.

There are several statements that require some special type and do type conversion when neccessary. That’s the if-statement, while and do-while and the for-statement. They all require booleans, so other types are converted to boolean.

The most common operators are the mathematical operators, such as + and -, and the comparison operator == (and their comrades +=, -= etc. and !=). I will cover the uglier operators first.

Automatic type conversion when dealing with the + operator

The + operator is an ugly element of Javascript. While it’s also overloaded in other languages, it’s also clear (and intuitive) what happens there. That’s different from Javascript. What’s the intuitive way to add a boolean to an object? Is there any way to define some semantics for adding a boolean to an object? I can’t think of one. Yet it can be done in Javascript.

When dealing with two numbers, the + operator adds these. When dealing with two strings, it concatenates.

3 + 5;              // 8
"hello " + "world"; // "hello world"
"3" + "5";          // "35"

When one operand is a string and the other is not, the other is converted to a string and the result is concatenated.

"the answer is " + 42; // "the answer is 42"
"this is " + true;     // "this is true"
var a;
"a is " + a;           // "a is undefined"

In any other case (except for Dates) the operands are converted to numbers and the results are added.

1 + true;     // -> 1 + 1 -> 2
null + false; // -> 0 + 0 -> 0

Dates for some reason are converted to strings, and thus the two operands are concatenated.

new Date() + 86400000; // that's not adding one day to date!
// that results in "Tue May 19 2009 10:46:30 GMT+020086400000" or something

The comparison operator ==

The first book on javascript that I read was ppk on JavaScript. There I read […] An empty String ” becomes false. All other values become true.. Of course I had to test this by myself and tried to convert the string “0” to a boolean. How do you know if this converts to true? Compare it! (No, actually not. Don’t repeat my mistake. Read the next part of this series about how to explicitly convert types.) So I did this:

"0" == true;  // don't do this

To my surprise this evaluated to false. I even wrote an email to ppk to point out that error in his book, which I find quite embarassing by now.

The reason behind that is the unexpected ruleset of type conversion using the comparison operator. In my case I expected it to convert the string “0” to a boolean, but it did not. Actually, the boolean was converted to a number. Yes, to a number. In the next step “0” was converted to a number as well. Therefore these were the steps taken:

"0" == true;  // first step: convert true to a number
"0" == 1;     // second step: convert "0" to a number
0 == 1;       // last step: compare
false;

That tought me a lot about javascript.

If you compare two values of the same type using the comparison operator no type conversion is done (although the results sometimes are surprising, I might cover this in an own article).

So it comes down to compare two values of different types. The first rule is: null and undefined are equal.

null == undefined; // true

The second rule is: when in doubt convert to number. If you compare a string and a number, convert the string to a number. If you compare a boolean to something else, convert the boolean to a number. On the other hand, if you compare an object to something else, convert it to a primitive by calling its valueOf method (and if that does not return a primitive call toString) and go on.

The Date object is different of course. Its valueOf normally returns a number, yet in combination with the comparison operator it returns a string representation.

This table shows it all. Note that the comparison operator is commutative, that means x == y and y == x return the same value.

Rules of conversion using x == y</caption>
  <thead>
    <tr>
      <th>type of x</th>
      <th>type of y</th>
      <th>result</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>null</td>
      <td>undefined</td>
      <td>true</td>
    </tr>
    <tr>
      <td>number</td>
      <td>string</td>
      <td>x == Number(y)</td>
    </tr>
    <tr>
      <td>boolean</td>
      <td>any, except for string</td>
      <td>Number(x) == y</td>
    </tr>
    <tr>
      <td>object</td>
      <td>string or number</td>
      <td>primitive representation of x == y</td>
    </tr>
    <tr>
      <td colspan="2">any other case</td>
      <td>false</td>
    </tr>
  </tbody>
</table>


<h3> The -, *, / and % operator </h3>

That's easy. When dealing with these operators convert the operands to number.

<pre class="prettyprint">
3 / "3";    // 1
"3" - true; // 2
null * "3"; // 0
"42" % "5"; // 2

The relational operator <

You can either compare strings or numbers. If you try to compare other types, convert the operands to numbers. Even Dates comply with that. Then you have two numbers to compare, and that's easy.

true < 2;                // 1 < 2, true
true < null;             // 1 < 0, false
"3" < 4;                    // 3 < 4, true
new Date() < 1234567890000; // false, if your clock is set correctly
{ valueOf : function () { return 3; }} < 4; // 3 < 4, true

The logical operators && and ||

The logical operators in javascript work on any type, unlike in Java. And unlike in Java, they do not return a boolean value. Still they expect boolean values and if not given two the operands are converted to boolean.

So technically that's a simple case. The implications, however, are immense. If you understand what happens you rose to a higher level of javascript development. If you like you may call yourself a ninja now.

Though the logical operators implicitly convert the operands to boolean (not neccessarily all, depending on the context), not the boolean value is returned but the operand itself.

var a = 0 || "4";
// a is now "4"

This comes in handy when supplying default values. Assume a function that returns the day of a year for a given date. If no date is supplied, the current date is taken:

function getDayOfYear = function (date) {
  date = date || new Date();
  var first = new Date(date.getFullYear(), 0, 1);
  return Math.floor((date - first) / 86400000) + 1;
}

In DOM scripting the logical or operator helps avoid browser incompabilities:

function doSomethingOnClick (event) {
  event = event || window.event;
  var target = event.target || event.srcElement;
}

In line 2 we look if the parameter event has been set (W3C event model) or not (Microsoft event model). In line 3 we get the element the action occured on according to the W3C model or the Microsoft model respectively.

You can use the logical and operator to do null checks before accessing object properties:

function setBackground (element, color) {
  if (element && element.style) {
    element.style.backgroundColor = color;
  }
}

Line 2 is a null check for both element and element.style.

Summary

Automatic type conversion happens in many cases. In most cases it is somewhat logical, in others you either need to know exactly what you're doing or you need to do an explicit type conversion. How to do this is covered in the upcoming third part of this series.

The following two tabs change content below.
  • Bio
  • Latest Posts

Matthias Reuter

Latest posts by Matthias Reuter (see all)

  • On the phone with Mom – Throttle and Delay DOM-Events in Javascript - November 17, 2011
  • So your dropdowns won’t open in IE7? - November 11, 2011
  • User-agent sniffing is back - February 15, 2011
« All about types in Javascript – The basics
All about types in Javascript – Explicit type conversion »

Tags

android code jam code puzzle hackercup hosting java javascript linux permutations project euler python raspberry pi server

Recent Posts

  • Raspberry Pi Supply Switch, start and shut down your Pi like your PC
  • Infinite House of Pancakes – code jam 2015
  • google code jam 2014 – magic trick
  • DIY: automated encrypted windows server backup
  • Generating random numbers and strings in Java

Copyright

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
© united-coders

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close