Prośba o wyjaśnienie domykania funkcji w przykładowym kodzie.

Odpowiedz Nowy wątek
2019-03-08 18:15

Rejestracja: 3 lata temu

Ostatnio: 4 miesiące temu

0

Witajcie,

w wytłumaczeniu poniższego kodu czytam:

"zmienna niezależna zostaje zapisana w środowisku funkcji getValue. Jednak funkcja getSecret nie zwraca funkcji getValue, dlatego też nigdy nie zobaczymy domknięcia poza kontekstem, w którym jest tworzone".

O co dokładnie chodzi w tym wyjaśnieniu?


var secret = "007";

function getSecret() {
     var secret = "008";

    function getValue() {
           return secret;
   }
    return getValue();
 }
 getSecret()'

Pozostało 580 znaków

2019-03-08 19:01
Moderator

Rejestracja: 12 lat temu

Ostatnio: 7 godzin temu

Lokalizacja: Wrocław

1

Jako że wewnątrz funkcji getSecret od razu wywołujesz getValue (return getValue();), tak naprawdę funkcja getValue nigdy nie opuszcza scope'u getSecret (dlatego też nie jesteśmy w stanie zauważyć domknięcia w akcji - ponieważ po zakończeniu działania getSecret wszystko już się wykonało).

Możemy podejść do problemu nieco inaczej:

function getSecret() {
    var secret = "008";

    function getValue() {
        return secret;
    }

    return getValue; // zwróć uwagę na brak nawiasów w tym miejscu...
}

console.log(getSecret()()); // ... i podwójną parę nawiasów tu

W tym wariancie kodu funkcja getValue "ucieka" poza getSecret i widzimy domknięcie w akcji - mimo że funkcja getSecret przestała się wykonywać, getValue nadal ma dostęp do kontekstu (zmiennej secret).


edytowany 2x, ostatnio: Patryk27, 2019-03-08 19:02
Dopytam jeszcze 'co dokładnie znaczą te dwie pary nawiasów? Pierwsza, że to funkcja..a ta druga para? - Kubs 2019-03-09 16:58

Pozostało 580 znaków

2019-03-08 20:28

Rejestracja: 3 lata temu

Ostatnio: 4 miesiące temu

0

Dziękuje.
Czyli to domknięcie polega (w tym przypadku) na tym, że getValue poza funkcją niejako dorzuca do getSecret wartości ze swojego środowiska, czym samym niejako domyka/dopełnia tą funkcję. Dobrze mówię?

I druga rzecz:

var secret = "007";

function getSecret() {
     var secret = "008";

    function getValue() {
           return secret;
   }
    return getValue();  // czyli wywołanie tutaj getValue(), nie ma sensu bo wywołane jest wcześniej. Czy tak?
 }
 getSecret()

//natomiast w twoim kodzie następuje zwrócenie wywołanej wcześniej funkcji

return getValue;

//czy tak?

Pozostało 580 znaków

2019-03-08 21:08
Moderator

Rejestracja: 12 lat temu

Ostatnio: 7 godzin temu

Lokalizacja: Wrocław

0

Ad 1: Tak, dokładnie o to chodzi w domknięciu.

Ad 2: Wołanie getValue() ma sens, tylko że nie widać wtedy efektów domknięcia :-)


A..ok ma sens ponieważ zwracamy wartość z getValue do getSecret(). :) - Kubs 2019-03-09 18:31

Pozostało 580 znaków

2019-03-08 22:47

Rejestracja: 3 lata temu

Ostatnio: 4 miesiące temu

0

Dzięki. Dopytam jeszcze, kiedy w realnej sytuacji moglibyśmy dokładnie taki kod użyć? Mógłbyś podać przykład?

Pozostało 580 znaków

2019-03-09 08:43
Moderator

Rejestracja: 12 lat temu

Ostatnio: 7 godzin temu

Lokalizacja: Wrocław

1

Domknięć możesz używać na przykład do budowania fabryk:

function createHeroFactory(name, health) {
  function createHero() {
    return { name, health };
  }

  return createHero;
}

const supermanFactory = createHeroFactory('Superman', 1000);

console.log(supermanFactory()); // stworzy nową instancję supermana
console.log(supermanFactory()); // stworzy nową instancję supermana

Innym, nieco bardziej typowym przykładem wykorzystania domknięcia, mogłoby być:

<body>
  <div class="alert" data-name="hello"></div>
  <div class="alert" data-name="world"></div>
</body>

<script>
$('.alert').each(function() {
  const alertName = $(this).data('name');

  $(this).on('click', function() {
    console.log(alertName);
  });
});
</script>

edytowany 1x, ostatnio: Patryk27, 2019-03-09 08:43
Pokaż pozostałe 2 komentarze
$(...).each(...) wyszukuje wszystkie elementy DOM pasujące do wskazanego selektora i dla każdego po kolei uruchamia przekazywaną funkcję. $(this).on('click', ...) z kolei jest odpowiednikiem addEventListener, czyli umożliwia przypisanie funkcji, która zostanie uruchomiona na jakieś zdarzenie. Domknięcie w tym kodzie widać na zmiennej alertName. - Patryk27 2019-03-09 17:42
Dzięki. Próbuje jeszcze zrozumieć to zamknięcie tutaj. Czyli alertName referuje do środowiska z hello oraz world. Ale w którym momencie dokonuje się tutaj to domknięcie? Wykonuje je zmienna?? Jestem na etapie wiedzy, że funkcja dokonuje domknięcia. :) - Kubs 2019-03-09 18:22
Zauważ, że w drugiej anonimowej funkcji (przekazywanej do wywołania $(this).on('click', ...)) nie deklarujemy nigdzie zmiennej alertName - jest ona automatycznie łapana z funkcji wyżej (przekazywanej do $('.alert').each(...) - w związku z tym właśnie mamy tutaj do czynienia z domknięciem. - Patryk27 2019-03-09 18:43
..a dlaczego tutaj użyłeś dwa razy funkcji anonimowej? Bo po prostu nie było potrzeby w tym przykładzie nadawać jej nazwy? Wybacz, że tak ciągnę temat. - Kubs 2019-03-09 19:10
Tak, nie było tutaj potrzeby ich nazywać :-) - Patryk27 2019-03-09 20:43

Pozostało 580 znaków

2019-03-09 13:21

Rejestracja: 1 rok temu

Ostatnio: 2 tygodnie temu

0

One of the most powerful mechanisms for program structuring [...] is the block and procedure concept. [...] A procedure which is capable of giving rise to block instances which survive its call will be known as a class; and the instances will be known as objects of that class. [1]

Zaimplementujmy klasę i stwórzmy jej instancję (obiekt):

const newStack = () => {
    const items = []
    return {
        depth: () => items.length,
        top: () => items[items.length - 1],
        pop: () => { items.pop() },
        push: newTop => { items.push(newTop) },
    }
}

const s = newStack()

[1] https://dl.acm.org/citation.cfm?id=1243383

edytowany 1x, ostatnio: Mózg, 2019-03-09 13:24

Pozostało 580 znaków

2019-03-09 16:50

Rejestracja: 3 lata temu

Ostatnio: 4 miesiące temu

0

Nie za bardzo rozumiem... czyli tutaj właściwości push przypisany jest nowy obiekt, który pobiera zmienną items na której to wywoływana jest metoda push przekazująca jako argument obiekt newTop? Ależ się zakręciłem :) .Mógłbyś proszę dokładnie wyjaśnić (najlepiej linijka po linijce) co tu się dzieje? Z góry dziękuję.

Pozostało 580 znaków

Odpowiedz

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