Wątek przeniesiony 2023-01-13 18:08 z JavaScript przez Riddle.

Czy to jest domknięcie?

0

Czy ten prosty przykład jest domknięciem? Gdy dodałem breakpointa to zmienna myName przechowywana jest w closure. Jak byście określili co to jest domknięcie w JavaScript ? Spotkałem się z takim zapisem: Domknięcie występuje wtedy, gdy funkcja może zapamiętać i uzyskać dostęp do swojego zakresu leksykalnego nawet po jej wywołaniu na zewnątrz tego zakresu.

const myName = "Leopard";

const printName = () => {
  debugger;
  console.log(myName);
}

printName();
2

Tylko że tutaj dalej jesteś w tym samym zakresie leksykalnym

{
  const myName = "Leopard";

  const printName = () => {
   debugger;
    console.log(myName);
  }
  //tu masz naturalny dostęp do zmiennej myName
  printName();
}

Ale jakby zrobić coś takiego

{
  const randomName = {
    const myName = "Leopard";

    const printName = () => {
     debugger;
      console.log(myName);
    }

    return printName; // czy to zwóci lambdaę?
  }
  // tu zmienna myName już "nie istnieje" a masz do niej dostęp
  randomName(); // wywołanie lamndy
}

BTW javascriptu nie znam za dobrze więc gdzieś znów mogłem się walnąć przy nawiasach czy returnach

O na wiki jest ładny przykład

function mnozenie_przez(x) {
  return function(y) {
    return x * y;
  };
}

var iloczyn_5_przez = mnozenie_przez(5);

console.log(iloczyn_5_przez(12)); // 60
0

Jak dla mnie to jest zwykłe użycie zmiennej. IMHO, żeby było domknięcie to myName musiałoby być zmienną lokalną/parametrem funkcji, która zwraca tę funkcję, więc coś takiego (może być jakiś błąd, nie testowałem):

const genPrintName = (name) {
  return () => {
    console.log(name);
  };
};

var printer = genPrintName("foo");
printer();
2
sajek587 napisał(a):
const myName = "Leopard";

const printName = () => {
  debugger;
  console.log(myName);
}

printName();

moim zdaniem to jest domknięcie (o ile myName to zmienna lokalna). to, że wywołujesz od razu tę funkcję (w tym samym zakresie leksykalnym) nie zmienia tego, że jest domknięciem. możesz jej nawet nie wywoływać, to nie ma znaczenia ile razy i gdzie jest wywołana. znaczenie ma to, do czego funkcja (domknięcie) się odwołuje i że może być wywołana z dowolnego miejsca.

ps. żeby była jasność :) jeśli myName to nie jest zmienna lokalna (czy też parametr funkcji, który w pewnym sensie też jest zmienną lokalną) to nie widzę tutaj domykania się.

0

Tutaj: właśnie został pokazany mój przykład z 1 posta i osoba na filmie mówi, że jest to domknięcie.

0
Wibowit napisał(a):
sajek587 napisał(a):
const myName = "Leopard";

const printName = () => {
  debugger;
  console.log(myName);
}

printName();

moim zdaniem to jest domknięcie (o ile myName to zmienna lokalna). to, że wywołujesz od razu tę funkcję (w tym samym zakresie leksykalnym) nie zmienia tego, że jest domknięciem. możesz jej nawet nie wywoływać, to nie ma znaczenia ile razy i gdzie jest wywołana. znaczenie ma to, do czego funkcja (domknięcie) się odwołuje i że może być wywołana z dowolnego miejsca.

ps. żeby była jasność :) jeśli myName to nie jest zmienna lokalna to nie widzę tutaj domykania się.

Czyli definicja domknięcia powinna brzmieć: Domknięcie występuje wtedy, gdy funkcja zapamiętuje i następnie wykorzystuje swój leksykalny zakres, nawet wtedy, gdy jest wywoływana w tym zakresie albo poza nim ?

Co oznacza dla Ciebie zmienna lokalna? Ta zmienna (myName) została użyta jako zmienna globalna.

1

za szybko odpisałeś :) a chciałem dopisać coś do posta

Spotkałem się z takim zapisem: Domknięcie występuje wtedy, gdy funkcja może zapamiętać i uzyskać dostęp do swojego zakresu leksykalnego nawet po jej wywołaniu na zewnątrz tego zakresu.

no właśnie. jeśli zmienna jest globalna to jak wyjść poza zakres globalny? zakres globalny jest cały czas dostępny, nie ma sensu się na nim domykać. no chyba, że javascript działa inaczej. nie jestem ekspertem z javascriptu.

1

Zamiast uczyć się z filmików randowmów ucz się z dokumecji/tutoriali od mozilli. Np https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

I tam jest kod:

function makeFunc() {
  const name = 'Mozilla';
  function displayName() {
    console.log(name);
  }
  return displayName;
}

const myFunc = makeFunc();
myFunc();

BTW random z filmika rozbudował jednak swój kod żeby był prawdziwym closure

0
KamilAdam napisał(a):

Zamiast uczyć się z filmików randowmów ucz się z dokumecji/tutoriali od mozilli. Np https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

I tam jest kod:

function makeFunc() {
  const name = 'Mozilla';
  function displayName() {
    console.log(name);
  }
  return displayName;
}

const myFunc = makeFunc();
myFunc();

BTW random z filmika rozbudował jednak swój kod żeby był prawdziwym closure

Ale na początku pokazuje identyczny przykład jak z mojego pierwszego posta. I jak dodałem sobie breakpointa tak jak w pierwszym przykładzie:

const myName = "Leopard";

const printName = () => {
  debugger;
  console.log(myName);
}

printName();

to w debugerze w closure jest zmienna myName. To czy na pewno nie jest to domknięciem?

screenshot-20230113141334.png

4

Moim zdaniem domknięcie występuje zawsze wtedy, kiedy funkcja operuje na zmiennych nie przekazanych jako argument.

Czyli moim zdaniem, to jest minimum do zaprezentowania domknięcia:

const a = 2;

function foo() {
  a; // domknięta "a"
}

Co ma oczywiste konsekwencje, o których mówili przedmówcy - tak domknięta wartość, może być później (ale nie musi) wyniesiona poza swój zakres leksykalny (do czego jest najczęściej używane domknięcie - ale nie jest to warunek konieczny).

Więc odpowiadając na pytanie z wątku, moim zdaniem: tak - to co zaprezentowałeś to jest domknięcie. Ale chciałbym jeszcze raz podreślić, to jest tylko moje rozumienie tego określenia.pq

1 użytkowników online, w tym zalogowanych: 0, gości: 1