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

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()'
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).

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?

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 :-)

0

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

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>
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

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ę.

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