Operators

An expression is a phrase in JavaScript that can be evaluated to produce a value. An operator allows building complex expressions by combining the values of its operands to produce to a new value. The basic arithmetic operators include addition +, subtraction -, multiplication *, division /, modulus %, exponentiation **, increment ++, and decrement --.

Bitwise operators

Bitwise operators convert a number to a 32-bit integer by dropping its fractional part and any bits beyond 32nd. The shift operators require the second operand to be in the range between 0 and 31. Infinity, -Infinity, NaN, and null all convert to 0 when used with bitwise operators.

const num1 = 0x1234;
console.log(num1.toString(2).padStart(32, 0));
// => 00000000000000000001001000110100

const num2 = 0x00ff;
console.log(num2.toString(2).padStart(32, 0));
// => 00000000000000000000000011111111

const bitwiseAnd = num1 & num2;
console.log(bitwiseAnd.toString(2).padStart(32, 0));
// => 00000000000000000000000000110100

const bitwiseOr = num1 | num2;
console.log(bitwiseOr.toString(2).padStart(32, 0));
// => 00000000000000000001001011111111

const bitwiseXor = num1 ^ num2;
console.log(bitwiseXor.toString(2).padStart(32, 0));
// => 00000000000000000001001011001011

const bitwiseNot = ~num1;
console.log((bitwiseNot >>> 0).toString(2).padStart(32, 0));
// => 11111111111111111110110111001011

const shiftLeft = num2 << 2; // second operand range: 0...31
console.log(shiftLeft.toString(2).padStart(32, 0));
// => 00000000000000000000001111111100

const shiftRight = num1 >> 4; // second operand range: 0...31
console.log(shiftRight.toString(2).padStart(32, 0));
// => 00000000000000000000000100100011

const shiftRightZeroFill = ~num1 >>> 2; // second operand range: 0...31
console.log(shiftRightZeroFill.toString(2).padStart(32, 0));
// => 00111111111111111111101101110010

Infinity >>> 0; // => 0
-Infinity >>> 0; // => 0
NaN >>> 0; // => 0
null >>> 0; // => 0

Equality operators

JavaScript uses two equality operators: loose equality == and strict equality ===. Only strict equality does NOT perform type conversion, whereas loose equality does type conversion. Reference types are equal only if they refer to the same object. NaN value does not equal to any other value, including itself. Loose inequality != and strict inequality !== operators do the opposite of their equality counterparts.

NaN === NaN; // => false
0 === -0; // => true
[] === []; // => false

null == undefined; // => true
'13' == 13; // => true
true == 1; // => true
false == '0'; // => true
[] == ''; // true

Comparison operators

Comparison operators >, >=, <, <= favor numbers and only perform string comparison if both operands are strings. In contrast, string concatenation operator + favors strings. For better string comparison, use String.localCompare() which takes into account alphabetical order of characters. If either operand is NaN, the result of comparison is false.

'1' + '2'; // => '12': string concatenation
'1' + 2; // => '12': 2 is converted to '2'
'11' < '3'; // => true: string comparison
'11' < 3; // => false: '11' converted to 11
'one' < 3; // => false: 'one' converted to NaN

The in operator

The in operator evaluates to true if the left-side value is the name of a property or method of the right-side object.

const point = {x: 1, y: 2};
'x' in point; // => true
'z' in point; // => false
'toString' in point; // => true

const arr = [4, 5, 6];
'0' in arr; // => true
1 in arr; // => true
3 in arr; // => false

The instanceof operator

The instanceof operator evaluates to true if the left-side object is an instance of the right-side class.

let d = new Date();
d instanceof Date; // => true
d instanceof Object; // => true
d instanceof Number; // => false

let a = [1, 2, 3];
a instanceof Array; // => true
a instanceof Object; // => true
a instanceof RegExp; // => false

Logical operators

Logical AND operator && does short-circuiting and stops evaluating the second operand if the first operand evaluates to false. Logical OR operator || also short-circuits by skipping evaluating the second operand if the first operand evaluates to true. Logical NOT operator ! inverts the boolean value of its single operand.

const max = 400, min = 100;
const stop = () => console.log('Stop');
(max === min) && stop(); // same as: if (a === b) stop();
let maxWidth = max || 500; // fallback to value
!true; // => false

Conditional operator

The conditional operator ?: is also called the ternary operator because it has three operands. If the first operand evaluates to true, then the second operand is evaluated and its value is returned. Otherwise, the third operand is evaluated and its value is returned.

let num = -5;
num = num > 0 ? num : -num; // absolute value

First-defined operator

The first-defined operator ?? returns the value of the left operand if it is not null or undefined. Otherwise, it returns the value of its right operand. It also performs short-circuiting: it only evaluates the right operand if the left operand evaluates to null or undefined.

const minWidth = 0;
const width = minWidth ?? 100; // => 0

The typeof operator

The typeof operator specifies the type of its single operand.

typeof undefined; // => 'undefined'
typeof null; // => 'object'
typeof true; // => 'boolean'
typeof NaN; // => 'number'
typeof 123.0; // => 'number'
typeof 123n; // => 'bigint'
typeof 'hello'; // => 'string'
typeof Symbol('hello'); // => 'symbol'
typeof function() {}; // => 'function'
typeof {}; // => 'object'
typeof []; // => 'object'
typeof /^HTML/; // => 'object'

The delete operator

The delete operator attempts to delete the object property or array element specified by its operand.

let myObject = { x: 1, y: 2 };
delete myObject.x; // => true
delete myObject.x; // => true
'x' in myObject; // => false
delete myObject.z; // => true

let myArray = [1, 2, 3];
delete myArray[1]; // => true
1 in myArray; // => false
myArray.length; // => 3: array length doesn't change

The comma operator

The comma operator , evaluates its left operand, then evaluates its right operand, and then returns the value of its right operand.

for (let i=0, j=10; i<j; i++, j--) {
  console.log(i+j);
}