Expressions
Expressions are something that can be evaluated to produce a value.
Primary expressions
These are the simplest kind of expressions: either a literal value, or a single variable reference.
3.14 // A number literal
false // A boolean literal
'Hello' // A string literal
null // A null value
undefined // An undefined value
/regex/ // A RegExp literal
this // reference to a single variable
Property access expressions
If you have a reference to an object type, you can access its properties using the . or [] operator. With the [] operator, you can access the property name using an expression.
const user = { firstName: 'John', lastName: 'Doe' };
const foods = ['noodle', 'sushi'];
// Using the . operator
console.log(user.firstName); //=> John
// Using the [] operator
console.log(user['last' + 'Name']); //=> Doe
console.log(foods[0]); //=> noodleAccessing property of null or undefined
If a is either null or undefined, you will get a TypeError when you try to do a.b or a['b'].
To prevent this, you could first check that the value of a is not falsy (which covers the case if it is null or undefined), or use optional chaining (see below).
// This will not throw if `user` is falsy
const firstName = user && user.firstName;
// This strategy could be cumbersome
// if you want to access `obj.a.b.c`
const value = obj && obj.a && obj.a.b && obj.a.b.c;
Optional chaining
You can use ?. or ?[] to only access a property if the lefthand side is not null or undefined (ES2020).
If the lefthand side is null or undefined, the whole expression will be evaluated as undefined.
const obj = {
a: { b: 123 }s
};
// Won't throw error
console.log(obj?.a?.b); //=> 123
console.log(obj?.a?.b?.c?.d); //=> undefinedYou can also use ?.() to optionally call a function at the end of a property access expression.
Note that it only checks that the lefthand side is not null or undefined. It does NOT check if the lefthand side is actually a function.
Call expression
A call expression invokes a function. The result of this expression is the return value of the called function, or undefined if it does not return a value.
Just put the name of the function (or an expression that evaluates to a function), and append it with (), optionally passing the arguments between the ( and ).
function sortArray(arr) {
return arr.sort();
}
const arr = [1, 5, 2, 4, 3];
console.log(sortArray(arr));Operators
Operators perform arithmetic expressions, comparison expressions, logical expressions, assignment expressions, and more.
There is a list of operator precendence, but for simplicity, remember PEMDAS in math. Use () to dictate which operation should go first.
Arithmetic operators
Increment/decrement operators
a++— return the current value ofa, then increment the value ofaby 1a--— return the current value ofa, then decrement the value ofaby 1++a— increment the value ofaby 1, then return the new value ofa--a— decrement the value ofaby 1, then return the new value ofa
Common math operators
a + b(addition) — addsaandba - b(subtraction) — subtractsawithba * b(multiplication) — multiplyaandba / b(division) — divideawithba % b(modulo) — computes the reminder ofadivided byba ** b(exponentation) — computeato the power ofb-a— negate the value ofa(plus to minus, vice versa)
Bitwise operators
a & b(bitwise AND) — performs boolean AND operation on each bit ofaandb, e.g.0b0011 & 0b0101⇒0b0001a | b(bitwise OR) — performs boolean OR operation on each bit ofaandb, e.g.0b0011 | 0b0101⇒0b0111a ^ b(bitwise XOR) — performs boolean XOR operation on each bit ofaandb, e.g.0b0011 ^ 0b0101⇒0b0110~a(bitwise NOT) — inverts all bits ofa
Shift operators
a << b(shift left) — shifts inbzero bits to the right ofa(the left-mostbbits are discarded), e.g.0b10101100_00000000_00000000_00001111 << 2⇒0b10110000_00000000_00000000_00111100a >> b(shift right with zero) — shifts inbzero bits to the left ofa(the right-mostbbits are discarded), e.g.0b10110000_00000000_00000000_11110101 >> 2⇒0b00101100_00000000_00000000_00111101a >>> b(shift right with sign) — shifts inbsign bits (the first bit ofa) to the left ofa(the right-mostbbits are discarded), e.g.0b10110000_00000000_00000000_11110101 >> 4⇒0b11111011_00000000_00000000_00001111
Logical operators
These may sound like they perform boolean operators, but they don't.
These operators can operate on non-boolean values. They just consider the truthiness/
Falsy values
These are the falsy values in JavaScript: false, undefined, null, 0, NaN, '' (the empty string).
Anything that is not falsy is truthy.
a && b(logical AND) — ifais falsy, returna(the falsy value), otherwise returnba || b(logical OR) — ifais truthy, returna(the truthy value), otherwise returnb!a(logical NOT) — ifais truthy, returnfalse, otherwise returntrue
Relational operators
Comparison operators
Comparison operators work on numbers and strings (any other types are converted first). For string comparison, remember that JavaScript strings are just sequences of 16-bit values (it compares which string has the first smaller/larger value from left to right).
If any of the operand is NaN, these comparisons always return false.
a < b— ifa<b, returntrue, otherwise returnfalsea > b— ifa>b, returntrue, otherwise returnfalsea <= b— ifa≤b, returntrue, otherwise returnfalsea >= b— ifa≥b, returntrue, otherwise returnfalse
Equality operators
There are loose (==) and strict (===) equality operators in JavaScript. The Loose equality operator performs type coercion before comparing the values, while strict equality operator never performs type coercion (if they are not the same type, then the result will be false).
Whenever possible, consider using === and !== over == and !=.
a == b(loose equality) — returntrueifais "equal" tob(after type conversion), otherwise returnfalse; e.g.'1' == 1⇒truea === b(strict equality) — returntrueifais equal toband they are of the same type, otherwise returnfalse; e.g.'1' === 1⇒false, but1 === 1⇒truea != b(loose inequality) — inverse ofa == ba !== b(strict inequality) — inverse ofa === b
Caveats/surprises (blame JavaScript magic):
NaN === NaN⇒falsenull == false⇒false
Checking for nullish value
You can usea == null to check if a is nullish (null or undefined).Assignment operators
The = operator
This simply assigns the right-hand side expression to a variable, an object property, or an array element. The return value of an assignment expression is the right-hand side value.
let a = 0;
a = (2 * 4) + 3;
console.log(a); //=> 11
console.log((a = 3) < 5); //=> true
console.log(a); //=> 3
const obj = { x: 1 };
obj.x = 2;
console.log(obj.x); //=> 2
const arr = [1, 2, 3];
arr[0] = 5;
console.log(arr); //=> [ 5, 2, 3 ]Assignment with operation
These are essentially shorthands for an assignment operation.
a += b— equivalent toa = a + ba -= b— equivalent toa = a - ba *= b— equivalent toa = a * ba /= b— equivalent toa = a / ba %= b— equivalent toa = a % ba **= b— equivalent toa = a ** ba <<= b— equivalent toa = a << ba >>= b— equivalent toa = a >> ba >>>= b— equivalent toa = a >>> ba &= b— equivalent toa = a & ba |= b— equivalent toa = a | ba ^= b— equivalent toa = a ^ b
Miscellaneous
Ternary operator
a ? b : c— ifais truthy, then returnb, otherwise returnc
Concatenation operator
a + b— ifaorbis string, concatenatesaandb, e.g.'Hello' + 'World'⇒HelloWorld
The ?? operator
a ?? b(nullish coalescing operator) — ifais not nullish (notnulland notundefined), then returna, otherwise returnb
Checking if a variable is defined
Use typeof myVar !== 'undefined' to check if a variable myVar has been defined.
If you use myVar !== undefined instead (note the subtleties), JavaScript will throw ReferenceError if myVar has not been defined.
The in operator
Checks if a property (a string, a number, or a Symbol) exists in an object.
const obj = { a: 1, b: 2, c: 3 };
console.log('a' in obj); //=> true
console.log('z' in obj); //=> false
const arr = [0, 1, 2];
console.log(0 in arr); //=> true
console.log(4 in obj); //=> falseThe delete operator
Deletes an object property or an array element. It returns true if the property/false otherwise.
Note that it is not the same as assigning an undefined value to the object property or the array element. The original "key" is removed entirely (using the in operator will return false).
const obj = { a: 1, b: 2, c: 3 };
// These are not the same operation
obj.b = undefined;
delete obj.c;
console.log(obj); //=> { a: 1, b: undefined }
console.log(obj.b, 'b' in obj); //=> undefined true
console.log(obj.c, 'c' in obj); //=> undefined falseThe typeof operator
Returns the "type" of its operand, which is one of: number, boolean, string, symbol, object, function, or bigint. Note that typeof null ⇒ 'object' ("null is a special kind of object").
console.log(typeof 2); //=> number
console.log(typeof 'aloha'); //=> string
console.log(typeof someUndefinedVariable); //=> undefined
console.log(typeof null); //=> objectThe instanceof operator
Checks if an object is an instance of a class. That is, obj instanceof Class returns true if a inherits from Class.prototype, directly or indirectly. (It will become clear once we talk about classes.)
let date = new Date();
// Remember that Date inherits from Object
console.log(date instanceof Date); //=> true
console.log(date instanceof Object); //=> true
console.log(date instanceof Number); //=> falseThe void operator
Discards the result of an expression, returning undefined.
console.log(void (1 + 3)); //=> undefinedThe , operator
a, b evaluates a, then evaluates b, then returns b.
// Look at the `i++, j--` part
for(let i=0, j=5; i < j; i++, j--) {
console.log(i, j);
}References
- JavaScript: The Definitive Guide, 7th Edition (David Flanagan) — Chapter 4. Expressions and Operators
- Annotated ECMAScript 5.1 (es5.github.io) — 11.9.3 The Abstract Equality Comparison Algorithm — http://es5.github.io/#x11.9.3
- Why (null == false) and (null == true) both return false? (Stack Overflow) — https://stackoverflow.com/a/27632549/5181368