JavaScript Notes
These notes summarize key ideas from the JetBrains 2024 JavaScript best-practices article, rewritten for clarity and ease of reference. Focus is on what the feature is, why it matters, and how to think about using it in real code.
Symbol Keys in Objects
JavaScript objects normally use string keys. Symbols let you attach properties that remain hidden from standard enumeration and avoid naming collisions.
Example
const obj = { name: 'Alice' }; const hiddenKey = Symbol('hidden'); obj[hiddenKey] = 'Secret Value'; console.log(Object.keys(obj)); // ['name'] console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(hidden)]
Notes
- Symbol properties do not show up in
for...in,Object.keys, or JSON output. - Helpful for framework internals or metadata that should not interfere with normal object usage.
- Not true privacy, but reduces accidental discovery or conflicts.
Map vs Object for Key-Value Storage
Objects convert all keys to strings and are best for structured data. Maps preserve key type and insertion order, making them more predictable for general key-value associations.
Example
const map = new Map(); const key = { id: 1 }; map.set(key, 'value'); console.log(map.get(key)); // 'value'
Notes
- Allows object, array, function, or any non-primitive as a key.
- Keeps insertion order stable.
- Ideal when you need a real dictionary or lookup table rather than a plain record.
Arrow Functions and Lexical Scope
Arrow functions reduce boilerplate and automatically bind this to their surrounding lexical scope.
Notes
- Avoids common
thismistakes in callbacks, event handlers, promises, and async workflows. - Shorter syntax improves readability for inline logic.
- Useful when methods rely on surrounding context without manual
.bind.
Private Fields in Classes
JavaScript now supports real private fields using the # prefix. These cannot be accessed or modified from outside the class.
Example
class Person { #name constructor(name) { this.#name = name; } getName() { return this.#name; } } const p = new Person('A'); console.log(p.getName()); // 'A'
Notes
- Enforces encapsulation at the language level rather than by naming convention.
- Prevents accidental misuse or external tampering.
- Improves long-term maintainability of class-based code.