0% found this document useful (0 votes)
1 views

JavaScript (ES6+)_ Core Programming Language for Front-End Logic

JavaScript (ES6+) is a core programming language for front-end web development that enables interactivity and dynamic content manipulation. It includes features such as variables, data types, functions, control flow, DOM manipulation, and modern capabilities like promises, async/await, and modules. The document also covers advanced concepts like closures, prototypes, async iteration, and performance optimization techniques.

Uploaded by

stef.spidy664
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views

JavaScript (ES6+)_ Core Programming Language for Front-End Logic

JavaScript (ES6+) is a core programming language for front-end web development that enables interactivity and dynamic content manipulation. It includes features such as variables, data types, functions, control flow, DOM manipulation, and modern capabilities like promises, async/await, and modules. The document also covers advanced concepts like closures, prototypes, async iteration, and performance optimization techniques.

Uploaded by

stef.spidy664
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

JavaScript (ES6+): Core programming language for front-end logic

Introduction to JavaScript (ES6+)

JavaScript (JS) is a programming language used to make web pages interactive. It enables
the dynamic manipulation of web content, allowing the creation of interactive websites, games,
applications, and more. JavaScript is the core language for front-end logic in web development.
It interacts with HTML (structure) and CSS (styling) to bring interactivity to web pages.

Why use JavaScript?

●​ Adds interactivity to web pages (e.g., form validation, pop-ups, dynamic content).​

●​ Manipulates the DOM (Document Object Model) to dynamically update web content
without reloading the page.​

●​ Allows handling of events like user clicks, form submissions, and mouse movements.​

●​ Can be used for both front-end and back-end development (with Node.js).​

●​ Supports modern features such as modules, promises, and async/await for handling
asynchronous code.​

Basic Syntax in JavaScript (ES6+)

JavaScript syntax includes keywords, operators, data structures, control structures, and
functions. Let’s dive into the foundational aspects first.

Variables

Variables are used to store data values.

js

CopyEdit

let name = "John"; // Declares a block-scoped variable

const pi = 3.14159; // Declares a constant value


var age = 30; // Declares a function-scoped or globally scoped
variable

●​ let: Block-scoped, preferred for variable declarations.​

●​ const: Immutable constant; its value cannot be reassigned.​

●​ var: Function-scoped, avoid using in modern development due to scope issues.​

Data Types

JavaScript has different types of values.

●​ Number: let num = 5;​

●​ String: let str = "Hello";​

●​ Boolean: let isActive = true;​

●​ Object: let obj = { key: 'value' };​

●​ Array: let arr = [1, 2, 3];​

●​ Null: let empty = null;​

●​ Undefined: let undef;​

Operators

●​ Arithmetic: +, -, *, /, %​

●​ Comparison: ==, ===, !=, !==, <, >, <=, >=​

●​ Logical: &&, ||, !​

Functions
Functions are blocks of code designed to perform a particular task. Functions are invoked or
called when needed.

Function Declaration:

js

CopyEdit

function greet(name) {

return `Hello, ${name}!`;

greet('Alice'); // "Hello, Alice!"

Arrow Functions (ES6):

js

CopyEdit

const add = (a, b) => a + b;

console.log(add(2, 3)); // 5

Control Flow

Control flow structures like if-else, for loops, and while loops control the logic of the program.

If-else Statements

js

CopyEdit

let age = 18;

if (age >= 18) {


console.log("You are an adult.");

} else {

console.log("You are not an adult.");

Switch Case

js

CopyEdit

let day = 2;

switch (day) {

case 1: console.log('Monday'); break;

case 2: console.log('Tuesday'); break;

default: console.log('Unknown Day');

Loops

●​ For Loop:​

js

CopyEdit

for (let i = 0; i < 5; i++) {

console.log(i); // Output: 0, 1, 2, 3, 4

}
●​ While Loop:​

js

CopyEdit

let i = 0;

while (i < 5) {

console.log(i);

i++;

Arrays and Array Methods

Arrays are ordered collections of values.

js

CopyEdit

let arr = [1, 2, 3, 4];

// Accessing elements

console.log(arr[0]); // 1

// Array Methods

arr.push(5); // Adds 5 to the end of the array

arr.pop(); // Removes the last element from the array

arr.shift(); // Removes the first element from the array


arr.unshift(0); // Adds 0 to the beginning of the array

arr.forEach(el => console.log(el)); // Iterates over the array


elements

Objects and Object-Oriented Concepts

Objects are collections of key-value pairs. JavaScript is object-based, and everything is an


object, including functions.

js

CopyEdit

let person = {

name: "Alice",

age: 25,

greet: function() {

return `Hello, my name is ${this.name}`;

};

console.log(person.greet()); // "Hello, my name is Alice"

ES6 Classes

Classes in JavaScript (introduced in ES6) are syntactic sugar for prototypes and are used to
create objects.
js

CopyEdit

class Person {

constructor(name, age) {

this.name = name;

this.age = age;

greet() {

return `Hello, I am ${this.name}`;

const john = new Person("John", 30);

console.log(john.greet()); // "Hello, I am John"

DOM Manipulation

JavaScript is heavily used to manipulate HTML content dynamically via the DOM (Document
Object Model).

js

CopyEdit

// Select an element

let heading = document.getElementById('title');


// Change text content

heading.textContent = 'Welcome to JavaScript';

// Add a new class to the element

heading.classList.add('highlight');

Event Handling

JavaScript allows you to add interactive elements that respond to user input such as clicks,
typing, and more.

js

CopyEdit

// Select the button

const button = document.querySelector('#btn');

// Add click event listener

button.addEventListener('click', function() {

alert('Button clicked!');

});

Promises and Async/Await (Asynchronous JavaScript)


JavaScript can handle asynchronous tasks, such as fetching data from APIs, using Promises or
async/await.

Promises

js

CopyEdit

let promise = new Promise(function(resolve, reject) {

let success = true;

if (success) resolve('Success!');

else reject('Failed!');

});

promise.then(function(result) {

console.log(result); // Output: Success!

}).catch(function(error) {

console.log(error);

});

Async/Await

js

CopyEdit

async function fetchData() {

let response = await fetch('https://api.example.com/data');

let data = await response.json();

console.log(data);
}

fetchData();

Modules (ES6+)

JavaScript allows you to split your code into separate files called modules. This helps in
organizing and maintaining the codebase.

Exporting a module:

js

CopyEdit

// math.js

export function add(a, b) {

return a + b;

Importing a module:

js

CopyEdit

// main.js

import { add } from './math.js';

console.log(add(2, 3)); // Output: 5


Modern JavaScript Features (ES6+)

Template Literals

js

CopyEdit

let name = "John";

console.log(`Hello, ${name}!`); // Template literal

Destructuring

js

CopyEdit

let person = { name: 'Alice', age: 25 };

let { name, age } = person;

console.log(name, age); // "Alice", 25

Spread and Rest Operators

●​ Spread: Expands an array or object into individual elements.​

js

CopyEdit

let arr = [1, 2, 3];

console.log(...arr); // Output: 1 2 3

●​ Rest: Combines individual elements into an array.​

js
CopyEdit

function sum(...args) {

return args.reduce((acc, val) => acc + val, 0);

console.log(sum(1, 2, 3)); // Output: 6

Cheat Sheet Summary

Here’s a brief overview of the key concepts in modern JavaScript:

●​ Variables: let, const, var​

●​ Data Types: Numbers, Strings, Arrays, Objects​

●​ Functions: Declaration, Arrow Functions​

●​ Loops: for, while, forEach​

●​ Conditionals: if-else, switch​

●​ Objects & Classes: Objects, ES6 Classes, Methods​

●​ Array Methods: push, pop, map, filter​

●​ DOM Manipulation: getElementById, querySelector, addEventListener​

●​ Event Handling: click, submit, input​

●​ Promises and Async/Await: Handling async operations​

●​ Modules: import, export​

●​ Template Literals: ${variable}​


●​ Destructuring: Object and array destructuring​

●​ Spread/Rest Operators: ...​

By learning these concepts, you will have a strong understanding of JavaScript and can apply it
effectively to front-end web development, making your pages interactive and dynamic. Let me
know if you'd like to explore any concept further!

Let's go deeper into the remaining advanced concepts and some specialized features of
JavaScript that are often overlooked but essential for mastering the language.

1. Closures

A closure is a function that remembers its lexical environment even when the function is
executed outside that lexical environment. Closures allow for data encapsulation.

js

CopyEdit

function outerFunction(outerVariable) {

return function innerFunction(innerVariable) {

console.log(`Outer Variable: ${outerVariable}`);

console.log(`Inner Variable: ${innerVariable}`);

};

const newFunction = outerFunction("outside");

newFunction("inside");

// Output:

// Outer Variable: outside


// Inner Variable: inside

Closures are useful when creating private variables or functions.

2. IIFE (Immediately Invoked Function Expression)

An IIFE is a function that runs as soon as it is defined. It’s mainly used for encapsulating code to
avoid polluting the global scope.

js

CopyEdit

(function() {

console.log("This is an IIFE");

})();

3. this Keyword

The value of this depends on the execution context (where the function is invoked).

●​ Global Context: this refers to the global object (Window in the browser).​

●​ Object Method: this refers to the object that called the method.​

●​ Event Listeners: this refers to the element that received the event.​

js

CopyEdit

const person = {

name: "Alice",

greet() {

console.log(this.name); // "Alice"
},

};

person.greet(); // "Alice"

4. Call, Apply, and Bind

These methods allow you to explicitly set this inside a function.

●​ call(): Calls a function with a given this value and arguments provided individually.​

●​ apply(): Similar to call(), but the arguments are provided as an array.​

●​ bind(): Returns a new function, where the this value is bound to the argument
passed.​

js

CopyEdit

const person1 = { name: 'John' };

const person2 = { name: 'Alice' };

function sayHello(age) {

console.log(`Hello, I'm ${this.name} and I'm ${age} years old.`);

sayHello.call(person1, 25); // "Hello, I'm John and I'm 25 years


old."
sayHello.apply(person2, [30]); // "Hello, I'm Alice and I'm 30 years
old."

const boundFunction = sayHello.bind(person1);

boundFunction(28); // "Hello, I'm John and I'm 28 years old."

5. Prototypes and Inheritance

In JavaScript, objects inherit properties from their prototype. All JavaScript objects have a
prototype, and JavaScript uses prototypes to share methods and properties between objects.

js

CopyEdit

function Person(name) {

this.name = name;

Person.prototype.greet = function() {

console.log(`Hello, my name is ${this.name}`);

};

const person1 = new Person('Alice');

person1.greet(); // "Hello, my name is Alice"

ES6 Classes are essentially syntactic sugar over JavaScript's prototype-based inheritance.

6. Async Iteration (for await of)


Async Iteration allows us to loop over promises. This is very useful when working with async
functions that return iterables.

js

CopyEdit

async function* asyncGenerator() {

yield "First";

yield "Second";

yield "Third";

(async () => {

for await (const value of asyncGenerator()) {

console.log(value);

})();

7. Generators

Generators are a special type of function that can be paused and resumed. They are defined
using the function* syntax.

js

CopyEdit

function* generatorFunction() {

yield 'First';

yield 'Second';
yield 'Third';

const generator = generatorFunction();

console.log(generator.next().value); // "First"

console.log(generator.next().value); // "Second"

console.log(generator.next().value); // "Third"

8. Symbol Data Type

Symbols are a new primitive type in JavaScript that are unique and immutable. Symbols are
often used to create unique keys in objects.

js

CopyEdit

let sym1 = Symbol("identifier");

let sym2 = Symbol("identifier");

console.log(sym1 === sym2); // false (every Symbol is unique)

9. Map and Set

●​ Map: Stores key-value pairs where keys can be any data type (similar to objects but with
more flexibility).​

●​ Set: Stores unique values of any type.​

js

CopyEdit
// Map

let map = new Map();

map.set('name', 'Alice');

console.log(map.get('name')); // "Alice"

// Set

let set = new Set();

set.add(1);

set.add(2);

set.add(1); // Duplicate, won't be added again

console.log(set.size); // 2

10. WeakMap and WeakSet

●​ WeakMap: Similar to Map, but keys must be objects, and they are "weakly held,"
meaning if the object is garbage collected, the entry is removed.​

●​ WeakSet: Similar to Set, but stores only objects, and they are also weakly held.​

js

CopyEdit

let weakMap = new WeakMap();

let obj = {};

weakMap.set(obj, 'value');

obj = null; // The object can be garbage collected, removing it from


the WeakMap.
11. Event Loop and Async Programming

JavaScript is single-threaded. The event loop is responsible for managing the execution of
code, collecting events, and executing queued tasks.

The call stack runs synchronous code, while promises and asynchronous operations are
placed in the task queue (or microtask queue).

js

CopyEdit

console.log('Start');

setTimeout(() => {

console.log('Timeout'); // Executes after synchronous code is done

}, 0);

Promise.resolve().then(() => console.log('Promise')); // Executes


before setTimeout

console.log('End');

// Output:

// Start

// End

// Promise

// Timeout
12. Modules (ES Modules)

Modern JavaScript uses the module system to split code into manageable chunks. You can
import/export modules across files.

js

CopyEdit

// Export (module.js)

export const name = 'John';

export function greet() {

console.log('Hello');

// Import (main.js)

import { name, greet } from './module.js';

console.log(name); // "John"

greet(); // "Hello"

13. Nullish Coalescing Operator (??)

This operator is used to assign default values when a variable is null or undefined.

js

CopyEdit

let value = null;

let defaultValue = value ?? "default";

console.log(defaultValue); // "default"
14. Optional Chaining (?.)

The optional chaining operator (?.) allows you to safely access deeply nested object
properties without having to check each level manually.

js

CopyEdit

let user = { address: { city: 'New York' } };

console.log(user.address?.city); // "New York"

console.log(user.address?.zipcode); // undefined

15. Debouncing and Throttling

These techniques are useful for optimizing performance when an event (like scroll or resize) is
fired multiple times per second.

●​ Debouncing: Ensures a function is only called once after a delay.​

js

CopyEdit

function debounce(func, delay) {

let timer;

return function() {

clearTimeout(timer);

timer = setTimeout(func, delay);

};

}
●​ Throttling: Ensures a function is called at most once in a specified time interval.​

js

CopyEdit

function throttle(func, limit) {

let inThrottle;

return function() {

if (!inThrottle) {

func();

inThrottle = true;

setTimeout(() => inThrottle = false, limit);

};

Cheat Sheet Summary (Advanced Concepts):

●​ Closures: Functions that remember their lexical scope.​

●​ IIFE: Immediately Invoked Function Expressions for encapsulation.​

●​ this: Context-dependent keyword.​

●​ Call, Apply, Bind: Methods to set this context explicitly.​

●​ Prototypes: Shared methods and properties through inheritance.​


●​ Generators: Functions that can be paused and resumed.​

●​ Async Iteration: Using for await...of to loop through promises.​

●​ Symbol: Unique and immutable identifiers.​

●​ Map and Set: Data structures for storing key-value pairs and unique values.​

●​ WeakMap and WeakSet: Similar to Map/Set but for objects that can be garbage
collected.​

●​ Event Loop: Core of JavaScript's asynchronous behavior.​

●​ Modules: Organizing code into separate files and importing/exporting functionality.​

●​ Nullish Coalescing (??): Default assignment for null/undefined.​

●​ Optional Chaining (?.): Safe property access.​

●​ Debouncing and Throttling: Optimizing event handling.​

These concepts should cover almost every corner of JavaScript, from basics to more advanced
topics. Let me know if you need further exploration into any of these areas!

Let's dive into a few additional advanced JavaScript concepts that are often considered
niche or highly specialized, but crucial for becoming a complete JavaScript master.

1. Memoization

Memoization is a technique to optimize function calls by caching results of expensive


computations. This can significantly improve performance in cases where the same function is
called repeatedly with the same arguments.

js

CopyEdit

function memoize(fn) {

const cache = {};

return function (...args) {


const key = JSON.stringify(args);

if (cache[key]) {

return cache[key];

} else {

const result = fn(...args);

cache[key] = result;

return result;

};

const factorial = memoize(function (n) {

if (n === 0) return 1;

return n * factorial(n - 1);

});

console.log(factorial(5)); // 120

console.log(factorial(5)); // Retrieved from cache

2. Functional Programming Concepts in JavaScript

Functional programming is a programming paradigm where functions are treated as first-class


citizens. JavaScript allows for various functional programming techniques.
●​ Pure Functions: Functions that do not have side effects and return the same result for
the same input.​

●​ Higher-order Functions: Functions that take other functions as arguments or return


functions.​

Example of higher-order functions:

js

CopyEdit

function map(array, func) {

const result = [];

for (let i = 0; i < array.length; i++) {

result.push(func(array[i]));

return result;

console.log(map([1, 2, 3], (x) => x * 2)); // [2, 4, 6]

3. Currying

Currying is a functional programming technique where a function with multiple arguments is


transformed into a sequence of functions, each taking a single argument.

js

CopyEdit

function curry(fn) {

return function curried(...args) {


if (args.length >= fn.length) {

return fn.apply(this, args);

} else {

return function (...nextArgs) {

return curried.apply(this, args.concat(nextArgs));

};

};

function sum(a, b, c) {

return a + b + c;

const curriedSum = curry(sum);

console.log(curriedSum(1)(2)(3)); // 6

4. Tail Call Optimization (TCO)

In recursive functions, Tail Call Optimization (TCO) allows the last call of a function to be
optimized and avoids growing the stack. This helps improve the performance of recursive
functions.

js

CopyEdit

function factorial(n, acc = 1) {


if (n === 0) return acc;

return factorial(n - 1, n * acc); // Tail call

console.log(factorial(5)); // 120

Not all JavaScript engines support TCO yet, but it’s a useful concept to be aware of.

5. Typed Arrays and Buffers

Typed Arrays provide a way to work with binary data directly in memory. These are especially
useful when working with file APIs, WebGL, or any low-level buffer manipulation.

js

CopyEdit

// Creating a buffer of 8 bytes

let buffer = new ArrayBuffer(8);

// Creating a typed array to work with the buffer

let view = new Uint8Array(buffer);

view[0] = 255; // Max value for a Uint8Array

console.log(view[0]); // 255

6. Promises with Promise.allSettled() and Promise.race()

While Promise.all() is widely used, there are a few more advanced Promise methods:
●​ Promise.allSettled(): Waits for all promises to settle (either resolve or reject) and
returns an array of the outcomes.​

js

CopyEdit

const promises = [

Promise.resolve('Success'),

Promise.reject('Error'),

Promise.resolve('Another Success'),

];

Promise.allSettled(promises).then((results) =>

results.forEach((result) => console.log(result.status))

);

// Output:

// fulfilled

// rejected

// fulfilled

●​ Promise.race(): Returns the result of the first promise to settle (whether it resolves or
rejects).​

js

CopyEdit
const promise1 = new Promise((resolve) => setTimeout(resolve, 500,
'One'));

const promise2 = new Promise((resolve) => setTimeout(resolve, 300,


'Two'));

Promise.race([promise1, promise2]).then((result) =>


console.log(result)); // "Two"

7. JavaScript Proxy and Reflect API

The Proxy object allows you to create a proxy for another object and define custom behavior for
fundamental operations (e.g., property lookup, assignment, function invocation).

js

CopyEdit

const target = {

message1: "hello",

message2: "everyone",

};

const handler = {

get: function (target, prop, receiver) {

if (prop === 'message1') {

return "proxy says hello";

return Reflect.get(...arguments);

},
};

const proxy = new Proxy(target, handler);

console.log(proxy.message1); // "proxy says hello"

console.log(proxy.message2); // "everyone"

Reflect provides built-in methods that mirror many proxy handlers, offering a default behavior
that you can enhance in a proxy.

8. Intl API (Internationalization)

The Intl API helps format numbers, dates, and strings according to different locales.

js

CopyEdit

const number = 1234567.89;

// Format number according to the German locale

console.log(new Intl.NumberFormat('de-DE').format(number)); //
"1.234.567,89"

// Format date

const date = new Date();

console.log(new Intl.DateTimeFormat('en-GB').format(date)); //
"28/03/2025"
9. WeakRef and FinalizationRegistry (ES2021)

WeakRef allows you to hold weak references to objects, and FinalizationRegistry allows you
to register a callback when an object is garbage collected. These are useful for managing
memory in advanced applications.

js

CopyEdit

let obj = { name: 'John' };

let weakRef = new WeakRef(obj);

obj = null; // The object can be garbage collected now

console.log(weakRef.deref()); // Might return undefined if GC has


occurred

const registry = new FinalizationRegistry((heldValue) => {

console.log(`${heldValue} was garbage collected`);

});

registry.register(obj, 'Object 1');

10. At() Method for Arrays and Strings

Introduced in ES2022, the at() method allows you to access array/string elements using both
positive and negative indices.

js

CopyEdit

let arr = [1, 2, 3, 4, 5];


console.log(arr.at(-1)); // 5 (last element)

console.log(arr.at(0)); // 1 (first element)

let str = 'Hello';

console.log(str.at(-1)); // 'o' (last character)

11. Top-Level Await

Starting in ES2022, you can use the await keyword at the top level of a module (without
wrapping it in an async function).

js

CopyEdit

const data = await fetch('https://api.example.com/data').then((res) =>


res.json());

console.log(data);

12. BigInt

BigInt is a new data type in JavaScript to represent integers beyond the safe integer limit for the
Number type (2^53 - 1).

js

CopyEdit

let bigNumber = 9007199254740991n;

console.log(bigNumber + 1n); // 9007199254740992n

console.log(bigNumber + 2n); // 9007199254740993n


13. Pattern Matching (Proposal)

Pattern matching is a proposed feature (still under development) that is similar to switch
statements, but designed for more complex matching.

js

CopyEdit

// Future JavaScript (example syntax)

match (value) {

when { a: 1, b } -> console.log(`Matched with b = ${b}`),

when [1, 2, 3] -> console.log('Matched an array'),

else -> console.log('Default case')

14. Private Class Fields and Methods (ES2022)

JavaScript now supports private fields and methods in classes using the # prefix.

js

CopyEdit

class MyClass {

#privateField = 42;

#privateMethod() {

return 'This is private';

}
publicMethod() {

return this.#privateMethod();

const instance = new MyClass();

console.log(instance.publicMethod()); // "This is private"

console.log(instance.#privateField); // SyntaxError: Private field


not accessible

15. Nullish Assignment (??=) and Logical Assignment Operators

In ES2021, you have nullish assignment and logical assignment operators to shorten
common assignment patterns.

js

CopyEdit

let x = null;

x ??= 10; // Only assigns 10 if x is null or undefined

console.log(x); // 10

let y = true;

y &&= false; // Logical AND assignment

console.log(y); // false

let z = false;
z ||= true; // Logical OR assignment

console.log(z); // true

Quirky Behaviors of JS

JavaScript is known for some "weird" behaviors that often puzzle


developers, especially due to its type coercion rules. Understanding
these oddities can make you more confident in debugging and writing
error-free code. Let’s dive into some of the most confusing and quirky
behaviors of JavaScript:

1. The Difference Between == and ===

●​ ==: Performs type coercion before comparison. This means it tries


to convert the types to be the same before comparing them.​

●​ ===: Strict equality, meaning no type conversion takes place—both


the value and the type must be the same.​

Examples:

js

CopyEdit

1 == '1'; // true (type coercion occurs)

1 === '1'; // false (strict comparison, different types)

null == undefined; // true (they're considered equal in non-strict


comparison)

null === undefined; // false (different types)

true == 1; // true (boolean `true` is coerced to number `1`)


false == 0; // true (boolean `false` is coerced to number `0`)

'0' == 0; // true (string `'0'` is coerced to number `0`)

2. Type Coercion

Type coercion is when JavaScript automatically converts one data type


to another, such as strings to numbers or booleans to numbers.

Examples:

js

CopyEdit

5 + '5'; // "55" (number 5 is coerced to string and concatenated)

'5' - 2; // 3 (string '5' is coerced to number)

true + true; // 2 (boolean `true` is coerced to 1)

'5' + true; // "5true" (true is coerced to string)

'5' * 2; // 10 (string '5' is coerced to number)

null + 1; // 1 (null is coerced to 0)

undefined + 1; // NaN (undefined is not a number)

3. Weird Truthy and Falsy Values

In JavaScript, some values are considered falsy (meaning they behave


like false in a boolean context) and others are truthy.
Falsy Values:

●​ false​

●​ 0​

●​ "" (empty string)​

●​ null​

●​ undefined​

●​ NaN​

Everything else is truthy, even empty objects ({}) and empty arrays
([]).

Examples:

js

CopyEdit

Boolean(0); // false

Boolean(''); // false

Boolean([]); // true (empty array is truthy)

Boolean({}); // true (empty object is truthy)

Boolean(null); // false

Boolean(undefined); // false

Boolean(NaN); // false

// Logical examples

if ([]) {
console.log("Empty array is truthy!"); // This will run

if ({}) {

console.log("Empty object is truthy!"); // This will run

4. NaN: Not-A-Number, but a Weird Number

NaN stands for "Not-A-Number," but it is of type number. It behaves


strangely because NaN is not equal to itself.

Examples:

js

CopyEdit

typeof NaN; // "number"

NaN === NaN; // false (NaN is never equal to anything, not even
itself)

isNaN('Hello'); // true ('Hello' is not a number)

isNaN(123); // false (123 is a number)

isNaN(NaN); // true

Number.isNaN(NaN); // true

Number.isNaN('Hello'); // false (more reliable than global `isNaN`)


5. Object Comparison

Objects are compared by reference in JavaScript, not by value. This


means that two distinct objects with the same properties are not
equal.

Examples:

js

CopyEdit

let obj1 = { name: 'Alice' };

let obj2 = { name: 'Alice' };

console.log(obj1 == obj2); // false (different objects in memory)

console.log(obj1 === obj2); // false (different objects in memory)

let obj3 = obj1;

console.log(obj1 == obj3); // true (both variables reference the


same object)

console.log(obj1 === obj3); // true (same reference)

6. Addition vs Concatenation Confusion

In JavaScript, the + operator is used for both addition (with numbers)


and concatenation (with strings), leading to confusing results if the
types aren't clear.

Examples:
js

CopyEdit

1 + 2; // 3 (addition)

'1' + 2; // "12" (string concatenation)

1 + '2' + 3; // "123" (first '1' + '2' concatenates, then '12' + 3 is


still concatenation)

1 + 2 + '3'; // "33" (first 1 + 2 adds, then '3' concatenates)

'10' - 5; // 5 (string '10' is coerced to number for subtraction)

7. The typeof Operator

The typeof operator in JavaScript can give some unexpected results.

Examples:

js

CopyEdit

typeof null; // "object" (this is actually a bug in


JavaScript)

typeof []; // "object" (arrays are a type of object)

typeof function() {}; // "function" (functions have their own type)

typeof NaN; // "number" (NaN is considered a number)

typeof undefined; // "undefined"


typeof 123; // "number"

typeof 'hello'; // "string"

8. Automatic Semicolon Insertion (ASI)

JavaScript automatically inserts semicolons at the end of certain


lines if they're omitted, which can lead to unexpected behavior.

Example:

js

CopyEdit

// You might expect this to return an object

let a =

b: 1

};

console.log(a); // undefined! (because JavaScript automatically


inserts a semicolon after `let a =`)

let b = {

c: 1

};

console.log(b); // { c: 1 } (works fine with proper formatting)


9. Void Operator

The void operator evaluates an expression but returns undefined.

Example:

js

CopyEdit

console.log(void 0); // undefined

console.log(void (0 + 1)); // undefined (expression is evaluated, but


result is ignored)

10. JavaScript Arrays Are Just Objects

Arrays in JavaScript are special kinds of objects with numbered keys,


which leads to some odd behavior.

Example:

js

CopyEdit

const arr = [1, 2, 3];

arr['foo'] = 'bar'; // You can assign properties like an object

console.log(arr.length); // 3 (length doesn't count 'foo')

console.log(arr.foo); // "bar" (accessing property like an object)

11. Function Hoisting


Function declarations are hoisted to the top of the scope, meaning you
can call the function before it is defined in the code. But function
expressions (when a function is assigned to a variable) are not
hoisted.

Example:

js

CopyEdit

foo(); // "Hello" (works because foo is hoisted)

function foo() {

console.log("Hello");

// Function expressions are not hoisted

bar(); // Uncaught TypeError: bar is not a function

var bar = function () {

console.log("Hi");

};

12. Global Object Leakage

If you forget to declare a variable using var, let, or const, it will


be automatically created as a global variable. This can cause
unexpected issues in larger codebases.

Example:
js

CopyEdit

function test() {

x = 5; // Forgot to declare 'x'

test();

console.log(x); // 5 (now 'x' is a global variable)

13. this Keyword Confusion

The value of this in JavaScript depends on how a function is called.


This can change depending on whether you're in strict mode, or whether
the function is called as a method, constructor, or standalone.

Examples:

js

CopyEdit

function test() {

console.log(this);

test(); // In the browser: 'window' (global object)

let obj = {
method: test,

};

obj.method(); // 'this' is obj

new test(); // 'this' is a new empty object created by the


constructor

14. Arguments Object

JavaScript functions have access to an arguments object, which is an


array-like object containing the arguments passed to the function.
However, the arguments object can behave strangely in ES6+ code,
especially with default parameters or arrow functions.

Example:

js

CopyEdit

function example(a, b) {

console.log(arguments[0]); // 1

console.log(arguments[1]); // 2

example(1, 2);

// With default parameters

function example2(a = 10) {


console.log(arguments[0]); // undefined (because default parameter
is used)

example2();

Conclusion

These quirky behaviors in JavaScript can seem strange or confusing,


but they can also be incredibly powerful if understood properly. By
mastering these behaviors, you'll be more confident when debugging,
writing robust code, and avoiding common pitfalls!

You might also like