Core JavaScript Concepts: Types, DOM, and Browser APIs
Type Checking and Identification
JavaScript categorizes data into primitives and reference types. The typeof operator distinguishes most primitives (returning number, boolean, string, undefined, and function), but it falls short for objects, arrays, and null, all of which evaluate to "object". For precise type identification, Object.prototype.toString.call(value) yields specific strings like [object Array] or [object Null]. Alternatively, instanceof verifies an object's prototype chain against a constructor, returning a boolean.
Type Coercion and Conversion
Implicit type conversion occurs frequently: the binary + operator concatenates if either operand is a string, while arithmetic operators (-, *, /) force operands to numbers. The unary + operator also coerces values to numbers. Relying on implicit rules is error-prone; explicit conversion is preferred.
console.log(Number('12.5')); // 12.5
console.log(Number('12.5abc')); // NaN
console.log(parseInt('15.99px')); // 15
console.log(parseFloat('15.99')); // 15.99
console.log(String(123)); // '123'
String and Array Transformations
Strings and arrays can be interconverted using split() and join(). split(separator) breaks a string into an array, while join(separator) merges array elements into a string.
Array mutation methods:
push()/pop(): Add to or remove from the end.unshift()/shift(): Add to or remove from the beginning.splice(startIndex, deleteCount, ...items): Inserts, removes, or replaces elements at any position.slice(startIndex, endIndex): Returns a shallow copy of a portion without modifying the original.- Iteration methods:
forEach,map,filter,reduce,some,every.
DOM Event Handling
Levels and Delegation
DOM Level 0 assigns handlers via on<event> properties (e.g., onclick), which overwrite each other and lack a capture phase. DOM Level 2 uses addEventListener(event, handler, useCapture), allowing multiple handlers and supporting both capture (true) and bubble (false) phases.
Event delegation exploits event bubbling by attaching a single listener to a parent node to handle events triggered on its children, optimizing performance for dynamic elements.
Stopping Propagation and Defaults
To halt event bubbling: event.stopPropagation(). To prevent native browser behavior (like form submission or link navigation): event.preventDefault().
Function Context and Inheritance
call(), apply(), and bind() manipulate the this context. call and apply execute the function immediately with a specified this and arguments (comma-separated for call, array for apply). bind returns a new function permanently bound to the provided context.
Modern inheritance relies on the extends and super keywords, though context manipulation historically served as a mechanism for borrowing constructors.
Closures
A closure is created when an inner function retains access to its outer function's lexical scope, even after the outer function has finished executing. This enables data privacy and state preservation across invocations.
DOM Node Manipulation
parentNode.appendChild(node): Appends a child.parentNode.removeChild(node): Removes a child.parentNode.replaceChild(newNode, oldNode): Replaces a child.parentNode.insertBefore(newNode, referenceNode): Inserts before a reference node.node.cloneNode(true|false): Clones a node;truefor a deep clone including descendants.
Object Categories
- Native Objects: Constructed by the developer (e.g.,
Array,Object). - Built-in Objects: Provided by ECMAScript, instantly available (e.g.,
Math,JSON). - Host Objects: Supplied by the environment (e.g.,
window,documentin browsers).
Page Load Events
DOMContentLoaded fires when the HTML document is completely parsed, without waiting for stylesheets or images. The window.onload event waits for the entire page, encluding all dependent resources, to finish loading.
Equality Evaluation
Loose equality (==) performs type coercion before comparing values, which can lead to unexpected results. Strict equality (===) requires both type and value to match identically, with no implicit conversion.
Same-Origin Policy and Cross-Origin Requests
The Same-Origin Policy (SOP) blocks scripts from accessing resources with differing protocols, domains, or ports. Common cross-origin workarounds include CORS (server-side Access-Control-Allow-Origin headers) and JSONP, which bypasses SOP using <script> tags.
Array Deduplication
function extractUniques(dataset) {
const seen = new Set();
return dataset.filter(item => {
if (seen.has(item)) return false;
seen.add(item);
return true;
});
}
Dynamic Typing
JavaScript is dynamically typed, meaning variables are not bound to a specific data type and can be reassigned to values of different types during execution.
Undefined vs. Null
undefined: A variable declared but not assigned, or a non-existent object property.null: An intentional assignment representing an empty or non-existent value.typeof nullerroneously returns"object"due to a legacy bug.null == undefinedevaluates totrue, butnull === undefinedisfalse.
Coercion Nuances and Reference Types
In loose equality, booleans coerce to numbers (0 or 1), and strings may coerce to numbers. NaN is unique because NaN === NaN is false.
Objects are assigned by reference. Modifying a property through a new variable pointing to the same object alters the original.
const config1 = { setting: true };
const config2 = config1;
config2.setting = false;
console.log(config1.setting); // false
Variable Hoisting
Declarations using var and function declarations are hoisted to the top of their scope. Only the declaration moves, not the initialization.
var externalVar = 10;
function testScope() {
console.log(internalVar); // undefined
var internalVar = 20;
}
testScope();
Merging Arrays
const seqA = [1, 2];
const seqB = [3, 4];
const combined = seqA.concat(seqB);
const spreadMerge = [...seqA, ...seqB];
Function Creation Methods
- Declaration:
function compute(a, b) { return a + b; } - Expression:
const compute = function(a, b) { return a + b; }; - Arrow Function:
const compute = (a, b) => a + b;
Script Loading and Iframes
Placing scripts before </body> ensures the DOM is parsed before execution. The defer attribute delays execution until parsing finishes, while async executes scripts asynchronous.
Iframes embed external content but block the main page's onload event, add loading overhead, and lack semantic meaning.
DOM Content Update
document.write() overwrites the entire document if called after page load, whereas innerHTML modifies the subtree of a specific element, allowing partial updates.
Memory Leaks
Memory leaks occur when objects are no longer needed but remain in memory due to lingering references. Causes include forgotten timers, closures holding large references, detached DOM nodes, and circular references.
JSONP vs. AJAX
JSONP dynamically creates <script> tags, passing a callback function name to the server, which returns executable script. It is not true AJAX because it does not use XMLHttpRequest or Fetch APIs, and it only supports GET requests.
Browser Location Object
window.location.search: Returns the query string (e.g.,?id=1).window.location.hash: Returns the fragment identifier (e.g.,#top).window.location.reload(): Refreshes the current document.
Frontend Performance Optimizasion
Optimization involves minimizing HTTP requests, utilizing CSS sprites, enabling browser caching, compressing and bundling assets, and deferring non-critical JavaScript.
HTTP Methods and Status Codes
- GET: Retrieves data; parameters visible in the URL; length restricted.
- POST: Submits data; payload in the request body; supports larger data sizes.
Common Status Codes:
- 200: Success.
- 302: Temporary redirect.
- 304: Not Modified (cached resource used).
- 403: Forbidden.
- 404: Not Found.
- 500: Internal Server Error.
Link vs. @import
The <link> tag is an HTML element that fetches CSS in parallel with the page. @import is a CSS rule that loads an external stylesheet, which can delay rendering due to sequential loading.
Synchronous vs. Asynchronous Execution
Synchronous code blocks the main thread until completion. Asynchronous operations delegate tasks (like I/O) to the environment, executing callbacks only when the tasks finish, keeping the main thread responsive.
Prototypal Inheritance
Every object holds a hidden link (__proto__ or accessed via Object.getPrototypeOf()) to its prototype, forming a chain. Property lookups traverse this prototype chain up to null if the property isn't found on the object itself.
setInterval Execution Nuance
setInterval(taskFn, 500) executes taskFn repeatedly every 500ms. setInterval(taskFn(), 500) executes taskFn immediately, evaluates its return value, and passes that (usually undefined) to the timer, failing to create the intended loop.