Operators

Increment and Decrement

The increment and decrement operators behave as in other languages.

let num1 = 2;
let num2 = 5;
let num3 = ++num1 + num2; // 8
let num4 = 2;
let num5 = 5;
let num6 = num4++ + num5; // 7
let num7 = 2;
num7--; // post increment
--num7; // pre increment

The increment and decrement operators work on any data type. See reference book for cases when values are not numeric.

Unary Plus

Unary plus behave just as Number() does.

let age = “1”;
age = +age; // age now has type Number with value 1

Unary Minus

Unary minus applies all of the rules as unary plus then negates the value.

let age = “1”;
age = -age; // age has the type Number with value -1

Logical Operators

Logical NOT

The Logical NOT operator (!) can be applied to any value. It converts the value to a Boolean using the rules for Boolean() discussed above, then negates it according to the logical NOT truth table.

NOT (!)
P !P
false true
true false
let done = false;
if (!done) {
    // do something
    done = true;
}

Logical AND

The logical AND operator (&&) works on all types and doesn’t necessarily return a Boolean (see reference book).

In cases were the arguments are Numbers, Booleans or Strings, the values are converted to Booleans and the logical AND of the Boolean values is returned.

AND (&&)
P Q P && Q
false false false
false true false
true false false
true true true
let result = true && false; // false

Logical OR

The logical OR operator (||) works on all types and doesn’t necessarily return a Boolean (see reference book).

In cases were the arguments are Numbers, Booleans or Strings, the values are converted to Booleans and the logical OR of the Boolean values is returned.

OR (||)
P Q P | Q
false false false
false true true
true false true
true true true
let result = true || false; // true
let myObject = preferredObject || backupObject;

In the example above, if preferredObject is null, then myObject is set to backupObject.

Multiplicative Operators

Multiply, divide and modulus work with Numbers and Floats as they do in Java. For all other types, the values are converted to numbers using the Number() cast function. Special conditions are given in the reference book.

let result = 3 * 2;  // multiply (6)
let result = 1 / 2;  // divide (0.5)
let result = 10 % 4; // modulus (2)

Addition

The plus binary operator (+) is overloaded, and so has different behavior for different types.

If both arguments are Numbers or Floats the result is as expected (extraordinary cases are discussed in the text).

let result = 3 + 5; // 8

If any of the arguments are strings, the result is a string.

let a = 3;
let b = 5;
let message = “3 + 5 = “ + a + b;     // “3 + 5 = 35”

Here, concatenation occurs from left to right, concatenating “3” first, then “5”.  If we want to print the sum, use parenthesis to sum the numbers first.

let message = “3 + 5 = “ + (a + b); // “3 + 5 = 8”

Subtraction

The subtraction binary operator (-) behaves as it does in Java for Number and Float types. Special cases are discussed in the text.

let result = 5 – 3; // 2

Relational Operators

The binary operators less than (<), greater than (>), less than or equal (<=) and greater than or equal (>=) return a Boolean. They behave as in Java when the arguments are Numbers or Floats.

If any of the arguments are numeric and the other is not, it is converted to a Number.

When used on strings, the operator is applied, from left to right, on pairwise characters using the character’s ASCII code.

let result = “a” < “b”;    // true
let result = “a” < “B”;   // false: 97 !< 66
let result = “a”.toLowerCase() < “B”.toLowerCase(); // true

Equality

The equal (==) and not equal (!=) binary operators perform type coercion to Numbers (if necessary) before assessing equality or non-equality. For example the string “55” is equal (==) to the number 55.

let result = “55” == 55; // true

Important case: Two Objects values are equal if they point to the same object.

Identical Equality

The identically equality (===) and the not identically equal operators (!==) behave as the equality operator except no type coercion is performed.  So here, the string “55” is not identically equal to the number 55.

let result = “55” === 55;  // false

Conditional Operator

The conditional operator is a very useful tertiary operator.

let result = Boolean_expression ? a : b;

Here result is set to either a or b depending on if the Boolean expression evaluates to true or false.  As an example, you can get the maximum of two numbers easily with the conditional operator.

let max = num1 > num2 ? num1 : num2;

Assignment Operator

The normal binary assignment operator is (=). Compound operators also exist.

  • *=
  • /=
  • &=
  • +=
  • -=
  • <<=
  • >>=
  • >>>=

The two statements below produce the save value in num.

let num += 10;
let num = num + 10;

Comma Operator

We can use the comma operator in assignment statements to declare and initialize multiple variables in the same line.  This is not recommended however.

let a=1, b=2, c=3;

Bitwise Operators

Bitwise operators are generally not used for arithmetic operations. They are used for

  • data compression
  • manipulating flag bits
  • low level programming

Signed integers use 32-bit representation with the 32nd bit holding 0 if the integer is positive and 1 if the integer is negative.

If the integer is positive, the remaining 31 bits determine the value of the integer.

If the integer is negative, it is stored in two’s complement format as described below.

  • Compute the binary representation of the absolute value of the value
  • Compute the 1’s complement of the number (swap 0’s and 1’s)
  • Add 1 to the result.

Example

2’s complement of -18

binary rep of 18: 0000 0000 0000 0000 0000 0000 0001 0010
1’s comp: 1111 1111 1111 1111 1111 1111 1110 1101
2’s comp: 1111 1111 1111 1111 1111 1111 1110 1110

-18: 1111 1111 1111 1111 1111 1111 1110 1110

Bitwise NOT

Bitwise NOT (~) is a unary operator that returns the 1’s complement of the number, that is, it flips all the bits.

NOT (~)
P ~P
0 1
1 0
let num = 24; // … 0001 0000
num = ~num;   // … 1110 1111

Bitwise AND

Bitwise AND (&) is a binary operator that returns a Number where each bit is the result of the logical AND operation applied to the pairs or bits at the same position in the two arguments.

AND (&)
P Q P & Q
0 0 0
0 1 0
1 0 0
1 1 1
let result = 11 & 13; // 0000 1011 (11)
                      // 0000 1101 (13)
                      -------------------
                      // 0000 1001 (9)

Bitwise OR

Bitwise OR (|) is a binary operator that returns a Number where each bit is the result of the logical OR operation applied to the pairs or bits at the same position in the two arguments.

OR (|)
P Q P | Q
0 0 0
0 1 1
1 0 1
1 1 1
let result = 11 | 13; // 0000 1011 (11)
                      // 0000 1101 (13)
                       -------------------
                      // 0000 1111 (15)

Bitwise XOR (Exclusive OR)

Bitwise XOR (^) is a binary operator that returns a Number where each bit is the result of the logical XOR operation applied to the pairs or bits at the same position in the two arguments.

XOR (^)
P Q P ^ Q
0 0 0
0 1 1
1 0 1
1 1 0
let result = 11 ^ 13; // 0000 1011 (11)
                      // 0000 1101 (13)
                       -------------------
                         0000 0110 (6)

Left Shift

The left shift operator (<<) shifts bits to the left filling the new bits on the right with 0’s.

let num1 = 6; // 0000 0110 (6)
let num2 = num1 << 3; // 0011 0000 (48)

Signed Right Shift

The signed right shift operator (>>) shifts bits to the right (not including the sign bit), filling the new bits on the left with 0’s.

let num1 = 6; // 0000 0110 (6)
let num2 = num1 >> 3; // 0000 0000 (0)

Unsigned Right Shift

The unsigned right shift operator (>>>) shifts bits to the right (including the sign bit), filling the new bits on the left with 0’s.

let num1 = -18;        // 1111 1111 1111 1111 1111 1111 1110 1110 (-18)
let num2 = num1 >>> 4; // 0000 1111 1111 1111 1111 1111 1111 1110 (large)