Uczę się JavaScript i natknęłam się na następujący fragment kodu:

var outerValue = true;

function outerFn(){
  assert( outerFn && outerValue, "These come from the closure." );
}

O ile rozumiem zamknięcia w powyższym kontekście, pozwalają na Outerfn, aby zobaczyć zmienną odzieżową.

Moje pytanie brzmi: Jak to jest inne niż inne języki programowania - takie jak Java na przykład? Właśnie oczekuje się, że zakres OuterValue pozwoli na to Outerfnowi go zobaczyć.

Dodano później:

    var outerValue = true;
    function outerFn() {
        console.log(outerValue);
    }

    function anotherFunction(arg){
        console.log("anotherFunction");
        arg.call(this);
    }

    anotherFunction(outerFn); 

Czy to jest lepszy przykład zamknięcia?

2
balteo 5 październik 2011, 13:07

3 odpowiedzi

Najlepsza odpowiedź

Twój przykład tak naprawdę nie ilustruje różnicy, ponieważ nie definiujesz zakresu wierzchniej. W JavaScript możesz gniazdować funkcje arbitralnie wewnątrz siebie, a zamknięcia upewniają się, że wewnętrzne funkcje mogą zobaczyć funkcje zewnętrzne, nawet po wywołaniu po wywołaniu funkcji zewnętrznych nie są już w zasięgu.

W Javie funkcje zagnieżdżające nie są (jeszcze) legalne, a zatem zamknięcia nawet nie wchodzą do gry. Posiadanie pola klasy w miejscu outerValue i metodę klasową w miejscu twojej funkcji jest inna, ponieważ dziedzina oczywiście jest związana z zakresem klasy, a nie metody.

1
Jonas Høgh 5 październik 2011, 09:18

Zrozumienie "Clowures" jako zdolność do zmiany zakresu wykonania funkcji lub sposobu. Oto przykład, w którym prowadzimy tę samą funkcję, modyfikując zakres "Klienta1", który "może" i klient2, który jest "John". Nie jest to możliwe w Javie.

<html>
<head>
    <script type="text/javascript" src="jquery-1.5.2.min.js"></script>
    <script type="text/javascript" >

    function assert(condition, message) {
        if (condition) {
            alert(message);
        }
    }

    function testClousures() {
        var client1 = {name: 'Mary', code: 123};
        var client2 = {name: 'John', code: 234};

        function outerFn(){ 
            assert( this.name == 'John', "These come from the closure." );
        }

        // Testing if client is John 
        outerFn.apply(client1);  // Fail
        outerFn.apply(client2);  // Success

    }

    function domReady() {
        $('#btn').click(function(){
            testClousures();
        });
    }
    </script>
</head>
<body onload="domReady()">
<br/>
<input id="btn" type="button" value="Test"></input>
</body>
</hmtl>
2
Nery Jr 5 październik 2011, 10:00

Wyobraź sobie funkcję outerFn() został przekazany jako wywołanie zwrotne. Czasami później, gdy biegnie, chociaż outerValue spadnie poza zasięgiem, nadal będzie dostępny w zamknięciu.

HTH

1
Daniel Elliott 5 październik 2011, 09:10