JS derangement
JavaScript / TypeScript Cheat Sheet — Things C# Doesn't Have¶
1. Spread operator ...¶
Expands an array or object into individual elements.
Arrays:
const a = [1, 2, 3];
const b = [4, 5, 6];
const combined = [...a, ...b]; // [1, 2, 3, 4, 5, 6]
const copy = [...a]; // [1, 2, 3] — new array, not a reference
Objects:
const user = { name: 'Abhishek', age: 30 };
const updated = { ...user, age: 31 }; // { name: 'Abhishek', age: 31 }
// later keys overwrite earlier ones
In function calls:
const nums = [1, 2, 3];
Math.max(...nums); // same as Math.max(1, 2, 3)
C# equivalent: roughly params + AddRange + new List(existing) — no single equivalent.
2. Rest operator ...¶
Opposite of spread. Collects remaining elements into an array. Same syntax, different context.
In functions:
function sum(...numbers: number[]) {
return numbers.reduce((acc, n) => acc + n, 0);
}
sum(1, 2, 3, 4); // 10
C# equivalent: params int[] numbers
In destructuring:
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first = 1, second = 2, rest = [3, 4, 5]
3. Destructuring¶
Pull values out of arrays or objects directly into variables.
Object destructuring:
const user = { name: 'Abhishek', age: 30, city: 'Kolkata' };
const { name, age } = user;
// name = 'Abhishek', age = 30
// rename while destructuring
const { name: userName } = user;
// userName = 'Abhishek'
// default value if property missing
const { name, country = 'India' } = user;
// country = 'India'
Array destructuring:
const [first, second] = [10, 20, 30];
// first = 10, second = 20
// skip elements
const [,, third] = [10, 20, 30];
// third = 30
In function parameters:
function greet({ name, age }: { name: string, age: number }) {
console.log(`${name} is ${age}`);
}
greet({ name: 'Abhishek', age: 30 });
forkJoin uses this:
forkJoin([getProfile(), getSettings()]).subscribe(([profile, settings]) => {
// array destructuring on the result
});
No C# equivalent. Closest is tuple deconstruction in C# 7+: var (x, y) = point;
4. Optional chaining ?.¶
Access nested properties without null checks. Returns undefined if anything in the chain is null/undefined instead of throwing.
const user = { address: { city: 'Kolkata' } };
// Without optional chaining
const city = user && user.address && user.address.city;
// With optional chaining
const city = user?.address?.city; // 'Kolkata'
// If address is null
const user2 = { address: null };
const city2 = user2?.address?.city; // undefined — no error thrown
On methods:
user?.getAddress?.(); // only calls if user and getAddress both exist
On arrays:
arr?.[0]; // safe index access
C# equivalent: ?. — same syntax, C# 6+. You already know this.
5. Nullish coalescing ??¶
Return right side only if left side is null or undefined. Not for falsy values.
const name = null ?? 'Anonymous'; // 'Anonymous'
const name2 = '' ?? 'Anonymous'; // '' — empty string is NOT null/undefined
const name3 = 0 ?? 42; // 0 — zero is NOT null/undefined
vs OR operator ||:
const name = '' || 'Anonymous'; // 'Anonymous' — treats empty string as falsy
const name2 = 0 || 42; // 42 — treats 0 as falsy
?? — only catches null/undefined. Safe for 0 and empty string. || — catches all falsy values. Dangerous for numbers and strings.
C# equivalent: ?? — same behaviour, same syntax.
6. Nullish coalescing assignment ??=¶
Assign only if current value is null or undefined.
let user = null;
user ??= 'Anonymous'; // user = 'Anonymous'
let name = 'Abhishek';
name ??= 'Anonymous'; // name stays 'Abhishek'
7. Array methods — JS vs C# mapping¶
const nums = [1, 2, 3, 4, 5];
// map → Select
nums.map(x => x * 2); // [2, 4, 6, 8, 10]
// filter → Where
nums.filter(x => x > 2); // [3, 4, 5]
// reduce → Aggregate
nums.reduce((acc, x) => acc + x, 0); // 15
// find → FirstOrDefault
nums.find(x => x > 3); // 4
// findIndex → no direct equivalent
nums.findIndex(x => x > 3); // 3 (index)
// some → Any
nums.some(x => x > 4); // true
// every → All
nums.every(x => x > 0); // true
// includes → Contains
nums.includes(3); // true
// flat — flatten nested arrays
[[1, 2], [3, 4]].flat(); // [1, 2, 3, 4]
// flatMap — map then flat in one step
[[1, 2], [3, 4]].flatMap(x => x); // [1, 2, 3, 4]
8. Object methods¶
const user = { name: 'Abhishek', age: 30 };
Object.keys(user); // ['name', 'age']
Object.values(user); // ['Abhishek', 30]
Object.entries(user); // [['name', 'Abhishek'], ['age', 30]]
// entries is useful for iteration
Object.entries(user).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// Object.assign — merge objects (spread is cleaner)
const merged = Object.assign({}, user, { city: 'Kolkata' });
// structuredClone — deep clone
const clone = structuredClone(user);
9. Template literals¶
const name = 'Abhishek';
const age = 30;
// Old way
const msg = 'Hello ' + name + ', you are ' + age;
// Template literal
const msg = `Hello ${name}, you are ${age}`;
// Multiline
const html = `
<div>
<p>${name}</p>
</div>
`;
// Expression inside
const result = `${2 + 2} is four`;
C# equivalent: $"Hello {name}" — same concept, different delimiter.
10. Short circuit evaluation¶
JS uses && and || for more than just booleans.
// && — return right side if left is truthy, otherwise return left
const result = user && user.name; // user.name if user exists, otherwise user (null/undefined)
// Common in JSX/templates
isLoggedIn && showDashboard(); // only calls if isLoggedIn is true
// || — return left side if truthy, otherwise right side
const name = inputName || 'Anonymous'; // 'Anonymous' if inputName is falsy
11. Comma operator and ternary¶
// Ternary — inline if/else
const label = count === 1 ? 'item' : 'items';
// Nested ternary — avoid, hard to read
const label = count === 0 ? 'empty' : count === 1 ? 'one item' : 'many items';
C# equivalent: condition ? a : b — same syntax.
12. typeof and instanceof¶
typeof 'hello'; // 'string'
typeof 42; // 'number'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof null; // 'object' ← famous JS bug, not actually an object
typeof {}; // 'object'
typeof []; // 'object' ← arrays are objects in JS
typeof function(){}; // 'function'
// instanceof — check class/constructor
[] instanceof Array; // true
user instanceof User; // true
13. Truthy and falsy — the JS gotcha¶
These values are falsy in JS — everything else is truthy:
false
0
-0
0n // BigInt zero
'' // empty string
null
undefined
NaN
// Gotcha — empty array and empty object are TRUTHY
if ([]) console.log('truthy'); // prints — array is truthy even if empty
if ({}) console.log('truthy'); // prints — object is truthy even if empty
// This is why ?? is safer than || for defaults
const count = 0;
count || 'none'; // 'none' — WRONG, 0 is a valid value
count ?? 'none'; // 0 — CORRECT
14. == vs ===¶
Always use ===. Always.
1 == '1'; // true — type coercion, compares value after converting
1 === '1'; // false — strict equality, type must match too
null == undefined; // true — special case
null === undefined; // false
0 == false; // true
0 === false; // false
== does type coercion. Unpredictable. === does not. Use === everywhere.