Adobe

decor

Web Platform Team Blog

Making the web awesome

JavaScript: Operators

In the previous article I talked about types and type coercion in JavaScript. In this one I want to talk more about how this coercion applies to JavaScript operators. Lets go over six major operators and look at how they work:

typeof

The typeof operator returns a string representation of the type of the passed expression. There are two major points to note:

  • Unresolvable references will produce "undefined", i.e. typeof a will return "undefined" if variable a was not declared.
  • typeof lies in two cases for null and for function () {}.

Apart from this, operator works pretty much as a lookup table:

Type of expression Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Object, that can’t be invoked "object"
Object, that can be invoked "function"

I marked with “⚠” two places where operator is misleading: type of null is Null and the actual type of any function is Object.

Subtraction

Converts both arguments to number. "8" - true is converted to 8 - 1. Very simple, indeed. Don’t expect the same from addition ;)

Addition

Addition is one of the trickiest operators in JavaScript. Lets see what is going on when you write a + b:

  1. Both arguments are converted to primitives. Lets call them A and B.
  2. If any of primitives is a String, concatenate A and B as strings.
  3. Otherwise add A and B as numbers.

For example:

 
8 + "5" ➙ "8" + "5" ➙ "85";
8 + true ➙ 8 + 1 ➙ 9;
"8" + true ➙ "8" + "true" ➙ "8true";
			

Less-than

In contrast to the addition operator, the less-than operator compares arguments as strings only if both of them are strings. To put it more formally, here are the steps:

  1. Both arguments are converted to primitives. Lets call them A and B.
  2. If both of primitives are Strings, compare A and B as strings.
  3. Otherwise compare A and B as numbers.

For example:

 
8 > "5" ➙ 8 > 5 ➙ true;
8 > true ➙ 8 > 1 ➙ true;
"8" > "18" ➙ true;
			

Strict Equals

The favourite operator of many, also known as triple equal (===) does things in a very simple way: checks if the arguments are of the same type and if they are, checks if they are equal. His little brother has a little bit more complicated character.

Equals

Ok, here it comes, the most hated operator of the language. According to the spec it works like so:

  1. First check for types, if they are the same, apply strict equals.
  2. If both arguments are either null or undefined, return true.
  3. If one of them is String and the other is Number, convert both to Number and apply strict equals.
  4. If one of them is Boolean, convert it to Number and go to 1.
  5. If one of them is String or Number and the other one is Object, convert object into primitive and go to 1.
  6. Return false.

This basically means that equals works like less-than, when the types of the arguments are different and like strict equals, when types are the same. The easy way to remember: when the types are different it converts both arguments into primitives, then into numbers, unless they both are strings. Oh, and null == undefined is true.

 
8 == "5" ➙ 8 == 5 ➙ false;
1 == true ➙ 1 == 1 ➙ true;

0 == "" ➙ 0 == 0 ➙ true;
0 == "0" ➙ 0 == 0 ➙ true;
"" == "0" ➙ false;

"1000" == "1e3" ➙ false;
1000 == "1e3" ➙ true;
5 == {valueOf: function () { return 5; }} ➙ 5 == 5 ➙ true;
			

These are not all the operators, but certainly the most tricky ones.  

6 Comments

  1. September 24, 2012 at 3:53 pm, Tobie Langel said:

    The major gotcha of the typeof operator which you didn’t mention is that it also returns "object"for arrays.

    • September 24, 2012 at 4:00 pm, Dmitry Baranovskiy said:

      It returns "object" for RegExp, Date and others too. It does make sense, but I agree having it return "array" for arrays would be useful.

      • November 06, 2012 at 2:36 am, Durgesh said:

        But the arrays are just wrapper over the object. Please correct me If I am wrong.

  2. September 24, 2012 at 10:17 pm, Mikhail Davydov said:

    You mention valueOf, but not say that this is the part of object ToPrimitive convertation. And depend on the second argument (hint passes) object converts to primitive using (valueOf || toString)() or (toString || valueOf)(). It may also throw an TypeError if both of them are not callable.
    Arrays with > are funny too :) http://jsfiddle.net/Sm8dT/

  3. September 25, 2012 at 7:13 am, Alexandr Subbotin said:

    The favourite operator of many, also known as triple equal (===) does things in a very simple way: checks if the arguments are of the same type and if they are, checks if they are equa

    … but not when both arguments are NaN, because NaN !== NaN