01

ES6 Modern Features

const / let / var ES6

const — value never changes. Use by default.
let — value can change. Use only when needed.
var — old way. Never use in modern JS.

JavaScript
const name = 'Rajesh';   // cannot reassign
let score = 10;         // can reassign
score = 20;             // ✅ fine
// name = 'John'        // ❌ error
ABAP Parallel
" const = CONSTANTS
CONSTANTS lc_name TYPE string
  VALUE 'Rajesh'.

" let = DATA
DATA lv_score TYPE i VALUE 10.
lv_score = 20.
Rule: Always start with const. Only switch to let if you need to reassign. Never use var.
Arrow Functions =>; ES6

Shorter syntax for functions. No function keyword needed.

Old Way
function add(a, b) {
  return a + b;
}
Arrow Function
const add = (a, b) => a + b;

// one param — no brackets
const double = n => n * 2;
Multi-line Arrow Function
const describe = (name, years) => {
  const level = years > 10 ? 'Senior' : 'Junior';
  return `${name} is a ${level} developer`;
};
Template Literals `${}` ES6

String interpolation using backticks. Replaces messy string concatenation.

Old Way (concatenation)
const msg = 'Hello ' + name +
  ', you have ' + years + ' years';
Template Literal
const msg = `Hello ${name},
  you have ${years} years`;
🔷
ABAP: Like |Hello { lv_name }| string template syntax in modern ABAP.
Destructuring { } ES6

Extract multiple values from objects or arrays in one clean line.

Old Way
const name  = dev.name;
const role  = dev.role;
const years = dev.years;
Destructuring
const { name, role, years } = dev;

// with rename
const { name: devName } = dev;
Array Destructuring
const [first, second, third] = ['blue', 'red', 'green'];
// first = 'blue', second = 'red', third = 'green'
🔷
ABAP: Like copying structure fields — lv_name = ls_dev-name. but all in one line.
Spread Operator ... ES6

Copy all properties of an object or elements of an array. Copy and override in one step.

Object Spread
const copy    = { ...dev };
const updated = { ...dev, role: 'Architect' };
const merged  = { ...dev, ...extra };
Array Spread
const a = [1, 2, 3];
const b = [4, 5, 6];
const all = [...a, ...b];
🔷
ABAP: Like ls_new = ls_old. then overriding specific fields after copy.
Optional Chaining ?. and ?? ES6

?. — safe property access. Returns undefined instead of crashing.
?? — nullish coalescing. Provide fallback if value is null/undefined.

Without — crashes if missing
// if dev.address is undefined → ERROR
const city = dev.address.city;
With ?. — safe
// returns undefined if address missing
const city = dev?.address?.city;

// with fallback using ??
const city = dev?.address?.city ?? 'Unknown';
🔷
ABAP: Like checking IS NOT INITIAL before accessing nested fields. Prevents dump equivalent.
02

DOM Manipulation

Finding Elements DOM
JavaScript
// Single element — returns first match
const btn  = document.querySelector('#myBtn');     // by id
const box  = document.querySelector('.myBox');    // by class
const h1   = document.querySelector('h1');         // by tag

// Multiple elements — returns NodeList (loop with forEach)
const btns = document.querySelectorAll('.btn');
btns.forEach(btn => btn.addEventListener('click', handler));
Reading & Changing Elements DOM
JavaScript
const el = document.querySelector('#myEl');

// Text content (safe — no HTML parsing)
el.textContent = 'New text';

// HTML content (parses HTML tags)
el.innerHTML = `<strong>Bold text</strong>`;

// Inline styles
el.style.backgroundColor = '#2E75B6';
el.style.display = 'none';

// CSS classes
el.classList.add('active');
el.classList.remove('active');
el.classList.toggle('active');    // adds if missing, removes if present
el.classList.contains('active'); // true/false

// Data attributes
el.getAttribute('data-category'); // read
el.setAttribute('data-category', 'new'); // write
Creating & Removing Elements DOM
JavaScript
// Create new element
const div = document.createElement('div');
div.className = 'card';
div.textContent = 'New card';

// Add to page
document.body.appendChild(div);           // at end
container.prepend(div);                   // at start

// Remove from page
div.remove();

// Build HTML directly (faster for multiple elements)
container.innerHTML += `<div class="card">${data}</div>`;
03

Arrays & Objects

Arrays & Objects — The Mental Model Data
ABAP
" Structure = one record
DATA: BEGIN OF ls_dev,
  name  TYPE string,
  years TYPE i,
END OF ls_dev.

" Internal Table = multiple records
DATA lt_devs LIKE TABLE OF ls_dev.
JavaScript
// Object = one record (like structure)
const dev = {
  name:  'Rajesh',
  years: 14
};

// Array = multiple records (like int. table)
const devs = [
  { name: 'Rajesh', years: 14 },
  { name: 'John',   years: 5  }
];
Index starts at 0 — devs[0] = Rajesh, devs[1] = John. Unlike ABAP where table index starts at 1.
04

Array Methods

forEach / map / filter / find Array
JavaScript — all 4 methods
const devs = [
  { name: 'Rajesh', years: 14, level: 'senior' },
  { name: 'John',   years: 4,  level: 'junior' },
  { name: 'Priya',  years: 10, level: 'senior' }
];

// forEach — loop through, no return (LOOP AT)
devs.forEach(dev => console.log(dev.name));

// filter — return matching items (LOOP AT WHERE)
const seniors = devs.filter(dev => dev.level === 'senior');

// map — transform every item, return new array (LOOP AT + modify)
const names = devs.map(dev => dev.name);
const tagged = devs.map(dev => ({ ...dev, name: dev.name + ' ⭐' }));

// find — return first match (READ TABLE WITH KEY)
const rajesh = devs.find(dev => dev.name === 'Rajesh');
🔷
forEach = LOOP AT  |  filter = LOOP AT WHERE  |  find = READ TABLE WITH KEY  |  map = LOOP AT + transform
05

Events

addEventListener — The 3 Parts Event

Every event has three parts: Target (what to watch), Type (what action), Handler (what to run).

JavaScript
//  target       type       handler
button.addEventListener('click',    () => { /* ... */ });
input.addEventListener('input',    (e) => handleInput(e));
input.addEventListener('focus',    () => input.classList.add('active'));
input.addEventListener('blur',     () => input.classList.remove('active'));
box.addEventListener('mouseenter', () => box.style.background = 'blue');
box.addEventListener('mouseleave', () => box.style.background = '');
window.addEventListener('scroll',   () => handleScroll());
window.addEventListener('load',     () => init());
Event Object & Delegation Event

e.target — the exact element that triggered the event.
Bubbling — events travel upward through all parents automatically.
Delegation — one listener on parent handles ALL children including dynamic ones.

Without delegation — fragile
// Must add listener to EACH button
// Dynamic buttons won't work
btn1.addEventListener('click', handler);
btn2.addEventListener('click', handler);
btn3.addEventListener('click', handler);
With delegation — robust
// ONE listener handles ALL buttons
// Works for dynamic buttons too
container.addEventListener('click', (e) => {
  if (e.target.classList.contains('btn')) {
    handler(e.target);
  }
});
🔷
e.target is like SY-UCOMM in ABAP — tells you exactly which action/element was triggered.
06

Promises & Async/Await

Promise — resolve / reject Async

A Promise = a value that will arrive in the future. Three states: PendingResolved or Rejected.

JavaScript
const myPromise = new Promise((resolve, reject) => {
  // async work here...
  if (success) {
    resolve('Data received!');  // like successful RFC return
  } else {
    reject('Connection failed');  // like RFC exception
  }
});

myPromise
  .then(result => console.log(result))  // success
  .catch(error  => console.log(error));  // failure
🔷
resolve = successful RFC/BAPI return  |  reject = RAISE EXCEPTION in RFC  |  .catch = CATCH cx_exception
async / await — Cleaner Promises Async

async — marks a function as asynchronous.
await — pauses THIS function only. Page stays alive. Continues when Promise resolves.

Promise .then chain
fetchData()
  .then(data => process(data))
  .then(result => display(result))
  .catch(err => handleError(err));
async/await — reads like ABAP
async function loadData() {
  try {
    const data   = await fetchData();
    const result = await process(data);
    display(result);
  } catch(err) {
    handleError(err);
  }
}
🔷
try/catch = TRY / CATCH in ABAP OOP  |  await pauses only the current function, NOT the whole page — unlike synchronous ABAP RFC calls.
07

Quick Reference

All Methods at a Glance Reference
Method / Syntax What it does ABAP Equivalent
querySelector('#id')Find element by idREAD TABLE ... WITH KEY
querySelectorAll('.cls')Find all matching elementsLOOP AT lt WHERE...
el.textContent = '...'Set text of elementlv_text = '...'
el.innerHTML = '...'Set HTML of elementlv_html = '...'
el.classList.add('x')Add CSS classSET PF-STATUS
el.classList.toggle('x')Add if missing, remove if presentIF x. CLEAR x. ELSE. x = 'X'. ENDIF.
el.getAttribute('data-x')Read data attributels_row-field
arr.forEach(x => ...)Loop through arrayLOOP AT lt INTO ls
arr.filter(x => cond)Return items matching conditionLOOP AT lt WHERE field = val
arr.map(x => transform)Transform every item, return new arrayLOOP AT lt + MODIFY
arr.find(x => cond)Return first matching itemREAD TABLE WITH KEY
const {a,b} = objExtract fields from objectlv_a = ls-a. lv_b = ls-b.
{...obj, x: 'y'}Copy object, override fieldls_new = ls_old. ls_new-x = 'y'.
obj?.prop?.subSafe nested accessCHECK ls IS NOT INITIAL.
val ?? 'fallback'Use fallback if null/undefinedIF lv IS INITIAL. lv = 'default'. ENDIF.
await fetchData()Wait for async operationCALL FUNCTION (synchronous)
08

Common Patterns

Pattern — Data Driven UI Pattern

Store data in arrays. Build HTML dynamically. Never hardcode UI content.

JavaScript — used in your portfolio
const data = [
  { name: 'Item 1', type: 'A' },
  { name: 'Item 2', type: 'B' }
];

function buildUI() {
  const container = document.querySelector('#container');
  container.innerHTML = '';

  data.forEach(({ name, type }) => {   // destructure inline
    container.innerHTML += `
      <div class="card" data-type="${type}">
        <h3>${name}</h3>
      </div>
    `;
  });
}

buildUI(); // call on page load
Pattern — Filter UI Pattern

Filter buttons pattern — reset all, activate one, show/hide cards. Used in your certifications section.

JavaScript — your certifications filter
function filterCards(category, clickedBtn) {
  // 1. Reset all buttons
  document.querySelectorAll('.filter-btn')
    .forEach(btn => btn.classList.remove('active'));

  // 2. Activate clicked button
  clickedBtn.classList.add('active');

  // 3. Show/hide cards
  document.querySelectorAll('.card').forEach(card => {
    const { category: cardCat } = card.dataset;
    const show = category === 'all' || cardCat === category;
    card.classList.toggle('hidden', !show);
  });
}
Pattern — Fetch API (coming next) Async

The standard pattern for calling any API — OData, REST, CAP service. You'll use this constantly.

JavaScript
async function fetchData(url) {
  try {
    // 1. Show loading state
    container.innerHTML = '⏳ Loading...';

    // 2. Make the call
    const response = await fetch(url);

    // 3. Parse JSON
    const data = await response.json();

    // 4. Use the data
    buildUI(data);

  } catch(error) {
    // 5. Handle errors
    container.innerHTML = `❌ Error: ${error.message}`;
  }
}