Operators



The most important thing about operators is type conversion. In Type Conversions, I've explained something about +, -, *, /, == and === (!= and !==).

If there's a string on either side of +, it will perform string concatenation. It's necessary to pay attention to operator precedence if you mix numbers and strings in the entire expression. For example:
js> 1 + 2 + '3';
33
js> '1' + 2 + 3;
123
js> '1' + (2 + 3);
15
js>

The first expression performs 1 + 2 and then concatenates the result 3 and the string '3'. The second expression performs string concatenation first, gets the result '12', and then performs concatenate the string with 3 so the final result is a string '123'. If you're not sure, use () to define precedence, such as the third expression above.

As for comparison operators, in addition to ==, ===, != and !== mentioned in Type Conversions, there are also >, >=, < and <=. In JavaScript, these operators can be used to compare not only numbers but also strings. If the operand type of these operators is stringthey will be compared character by character according to Unicode code points.

If a string and a number are on either side of these operators, type conversion will happen automatically. If the string operand represents a number, it will be converted to a number value and then compared with another operand. If the string operand doesn't represent a number, it will be converted to NaN, and the final result of comparison will be false undoubtedly.

In fact, objects can also be used as operands of >,> =, < and <=. It's possible to convert an object to a number and perform comparison if it owns a method valueOf which returns a number. Date is such an example:
js> var date = new Date();
js> date.valueOf();
1289293581594
js> date > 1289293581594;
false
js> date > 1289293581593;
true
js> date > new Date();
false
js> new Date() > date;
true
js> var obj = {
  >     valueOf : function() {
  >         return 100;
  >     }
  > };
js> 1 + obj;
101
js> 1 > obj;
false
js>


As shown in the above example, if an expression needs to convert objects to numbers, it will use the valueOf method. By default, valueOf returns the return value of toString. If you don't override valueOf, the return value of toString will be used in comparison.
js> var o1 = {};
js> o1.valueOf();
[object Object]
js> var o2 = {};
js> o2;
[object Object]
js> o1 >= o2;
true
js> o1 > o2;
false
js> o1 == o2;
false
js>


Be careful, if == used to compare objects, it will compare object's references. That's why o1 == o2 is false in the above.

If you want to check whether an object owns a property and produce a result true or false, you can use the in operator. For example: 
js> var obj = { x : 10 };
js> 'x' in obj;
true
js>


I'll introduce objects afterward. Here you can also see that the property name of an object is actually a string value.

If you want to know which constructor (or so-called class) an object is instantiated from, you can use instanceof. For example: 
js> [] instanceof Array;
true
js> [] instanceof Object;
true
js> [] instanceof Date;
false
js>


If the constructor of an object has no inheritance relationship with the right operand of instanceof, it returns false.

The typeof operator can also be used to get the type of an object or a value. It returns a string. For primitive types, it will return 'number' for  number values, 'string' for string values and 'boolean' for boolean values. As for other types, typeof returns 'function' for instances of Function, 'undefined' for the undefined value and 'object' for all other objects, including null.
js> typeof 1;
number
js> typeof '';
string
js> typeof true;
boolean
js> typeof function() {};
function
js> typeof undefined;
undefined
js> typeof {};
object
js> typeof null;
object
js>


We all know that && and || are used to check whether an AND or OR operation is evaluated to true, and both are short-circuit operators. For example, when the left operand of && evaluates to false, the overall result must be false immediately. The right operand will not be evaluated. As for ||, the left operand suffices to determine the truth if it's evaluated to true so it's not necessary to evaluate the right operand.

The && or || operator doesn't return true or false, however, but returns the evaluated operand while the overall expression is confirmed as true or false. For example:
js> 'left' && 'right';
right
js> 0 && 'right';
0
js> 'left' && 0;
0
js>


In the first example above, the left operand is a non-empty string. It's treated as true so the right operand is evaluated. The right operand is also a non-empty string so the overall expression will be true and 'right' is returned immediately. As for the second example, 0 is treated as false so it's not necessary to evaluate the right operand. The overall expression will be false and 0 is returned. The left operand of the third example is a non-empty string. It's treated as true so the right operand 0 is evaluated and treated as false. The overall expression is false right now so returns the right operand.

Examples of || are as follows:
js> 'right' || 'left';
right
js> 0 || 'left';
left
js> 'right' || 0;
right
js>


The short-circuit feature is useful. For example, if you want to provide a default value if a variable value is undefined, you can do as follows:
js> function doSome(arg) {
  >     var option = arg || 'default';
  >     print(option);
  > }
js> doSome();
default
js> doSome('caterpillar');
caterpillar
js>


I use a function as an example in the above code. You'll see more details about functions afterward. For example, if a function has too many parameters, you can merge them into an object. In fact, the above example is equivalent to use ?: operator.
js> function doSome(arg) {
  >     var option = arg ? arg : 'default';
  >     print(option);
  > }
js> doSome();
default
js> doSome('caterpillar');
caterpillar
js>


For the above two examples, || and :? have the same effect, but the convention is to use ||.

The void operator can be put before any value or expression. It always returns undefined. This is another way to get undefined. For some environments which the undefined keyword cannot be written directly, you can use void to get undefined. For example:
js> void 0;
js> typeof void 0;
undefined
js>