Learning
JavaScript

Függvények, scope, closures

Függvényformák, scope és hoisting, valamint a closures – a modern JavaScript egyik legfontosabb témaköre.

Függvények, scope, closures

Ez az oldal a teljes jegyzet 5–7. fejezetét bontja ki: függvények, scope & hoisting, closures.
Forrás: content/javascript/javascript-full.mdx.


1. Függvények – alapformák

Function Declaration

function osszead(a, b) {
  return a + b;
}

console.log(osszead(3, 4)); // 7

Tulajdonság: hoistolódik – a JS motor a teljes függvénydefiníciót a scope tetejére emeli, így a deklaráció előtt is hívható.


Function Expression

const osszead = function(a, b) {
  return a + b;
};

console.log(osszead(3, 4)); // 7

Itt a változó hoistolódik, de az értékadást csak azután kapja meg – ezért a deklaráció előtt hívni hibához vezetne.


Arrow function (=>)

Rövidebb szintaxis, és másképp kezeli a this‑t (lexikális, nem dinamikus) – erről bővebben a this oldalon.

// Hagyományos
const negyzetHagyomanyos = function(x) {
  return x * x;
};

// Arrow function – rövidebb
const negyzet = (x) => x * x;

// Több paraméter
const osszead = (a, b) => a + b;

// Több sor – kapcsos zárójel + return kell
const udvozlet = (nev) => {
  const uzenet = `Szia, ${nev}!`;
  return uzenet;
};

Mikor használj arrow‑t?

  • rövid, expression‑alapú függvényekhez,
  • callbackekhez (map, filter, event handler),
  • amikor a külső this‑t akarod megtartani (pl. setTimeout belsejében).

Paraméterek, default értékek, visszatérési érték

// Default paraméter
function udvozlet(nev = "Vendég") {
  return `Szia, ${nev}!`;
}

udvozlet();       // "Szia, Vendég!"
udvozlet("Adam"); // "Szia, Adam!"

// Ha nincs return, a függvény undefined-ot ad vissza
function semmi() {
  console.log("Csinálok valamit");
}

console.log(semmi()); // undefined

2. Scope és hoisting

Mi az a scope?

A scope (hatókör) határozza meg, hogy hol érhető el egy változó a kódban.

  • Global scope – mindenhol elérhető.
  • Function scope – egy függvényen belül érvényes.
  • Block scope{ ... } blokkon belül érvényes.

Global scope

const globalValt = "Mindenhol látható";

function pelda() {
  console.log(globalValt); // ✓
}

Globálison lehetőleg csak konstansokat és "app‑szintű" dolgokat tarts, a többi legyen közelebb a felhasználás helyéhez.


Function scope (var)

function pelda() {
  var benti = "Csak itt látható";
  console.log(benti); // ✓
}

// console.log(benti); // HIBA – a scope-on kívül

var változók function scope‑úak, ezért ciklusoknál / blokkos szerkezeteknél is a teljes függvényre vonatkoznak.


Block scope (let / const)

{
  let blockValt = "Csak ebben a blokkban";
  const masik = "Ez is";
}

// console.log(blockValt); // HIBA

for (let i = 0; i < 3; i++) {
  // i csak ebben a for-blokkban él
}
// console.log(i); // HIBA

Miért számít? Klasszikus példa:

// var – meglepő eredmény
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 3, 3, 3
}

// let – elvárt eredmény
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 0, 1, 2
}

var esetén a ciklus minden iterációja ugyanazt az i változót látja; mire a setTimeout callback lefut, a ciklus már végzett, i === 3.
let esetén minden iterációnak saját block‑scope i‑je van.


Hoisting – "felemelés"

A JavaScript értelmezéskor felemeli a deklarációkat a scope tetejére.

Function declaration hoisting

console.log(osszead(2, 3)); // 5 – működik

function osszead(a, b) {
  return a + b;
}

var hoisting

console.log(x); // undefined – nem hiba, de még nincs érték
var x = 5;
console.log(x); // 5

// A motor valójában így látja:
// var x;
// console.log(x); // undefined
// x = 5;
// console.log(x); // 5

let / const és a TDZ (Temporal Dead Zone)

// console.log(y); // HIBA: Cannot access 'y' before initialization
let y = 10;

let / const is "feljebb kerül" technikailag, de az inicializálásig Temporal Dead Zone‑ban van – addig nem hozzáférhető.

Interjú tipp: Hoisting = deklarációk scope tetejére emelése.
varundefined‑dal indul; let/const → TDZ, használat előtte hiba.


3. Closures

Alap definíció

Closure akkor jön létre, amikor egy belső függvény hozzáfér a külső függvény változóihoz, még azután is, hogy a külső függvény lefutott.

function kulso() {
  const uzenet = "Hello a külső függvényből!";

  function belso() {
    console.log(uzenet);
  }

  return belso;
}

const fuggvenyem = kulso(); // kulso lefutott
fuggvenyem();               // "Hello a külső függvényből!"

Itt a belso függvény “magával viszi” az uzenet változót – ez a closure.


Miért hasznos?

  1. Adatrejtés – "privát" változókat kapsz.
  2. Állapot megőrzése – függvényhívások között is megmarad az érték.
  3. Gyári függvények – paraméterezett függvénygenerálás.

Példa: számláló "privát" állapottal

function szamlaloLetrehoz() {
  let szamlalo = 0; // privát

  return {
    novelesek() {
      szamlalo++;
      return szamlalo;
    },
    csokkenres() {
      szamlalo--;
      return szamlalo;
    },
    ertek() {
      return szamlalo;
    }
  };
}

const szamlalo = szamlaloLetrehoz();
szamlalo.novelesek();  // 1
szamlalo.novelesek();  // 2
szamlalo.csokkenres(); // 1
szamlalo.ertek();      // 1

// Kívülről nem férsz hozzá:
// szamlalo.szamlalo → undefined

Példa: függvénygyár (factory)

function udvozloLetrehoz(nev) {
  return function() {
    console.log(`Szia, ${nev}!`);
  };
}

const adamUdvozlo = udvozloLetrehoz("Adam");
const peterUdvozlo = udvozloLetrehoz("Peter");

adamUdvozlo();  // "Szia, Adam!"
peterUdvozlo(); // "Szia, Peter!"

Mindkét visszaadott függvény a saját nev‑ét zárja körbe closure‑ben.


Klasszikus closure csapda: for + var + async

// Probléma
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 3, 3, 3 – nem 0, 1, 2
  }, 100);
}

Megoldás 1 – let:

for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 0, 1, 2
  }, 100);
}

Megoldás 2 – IIFE (Immediately Invoked Function Expression):

for (var i = 0; i < 3; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j); // 0, 1, 2
    }, 100);
  })(i);
}

Itt az IIFE paraméter (j) hoz létre új scope‑ot minden iterációhoz.


Összefoglaló – Függvények, scope, closures

  • Ismerd a három fő függvényformát: declaration, expression, arrow.
  • Scope:
    • var → function scope,
    • let / const → block scope.
  • Hoisting:
    • function declaration + var → felemelés a scope tetejére,
    • let/const → TDZ, használat előtt hiba.
  • Closure:
    • belső függvény megtartja a külső scope‑ot,
    • adatrejtésre és állapot megőrzésre nagyon erős eszköz.

Következő oldal:
Objektumok és prototípusok →

On this page