2016-11-04 4 views
0

Ich habe Somethings wie:, ich möchte einen Namen

var i = 0; 

var func = function(){ 
    console.log(i); 
}; 

func(); //0 

i++; 

func(); //1 

Ich möchte die zweite Konsole auch Ausgang ‚‘ haben, so ändere ich das Programm wie:

var i = 0; 

var func = (function(_i){ 
    return function(){ 
     console.log(_i); 
    }; 
})(i); 

func(); //0 

i++; 

func(); //0 

Ich weiß, wie es funktioniert, aber gibt es irgendwelche Namen oder Begriffe, solche Mechanismen zu beschreiben?

+1

Es heißt "pass by value" vs "erfassen Variable im Bereich". Beachten Sie, dass dies nur funktioniert, weil eine 'Zahl' ein Werttyp ist. Sie können diesen Trick nicht verwenden, um sich von einem Objekt zu lösen. – Thilo

Antwort

4

ich diesen Mechanismus "breaking the closure" Aufruf habe, obwohl ich Argumente in der Vergangenheit mit Menschen gehabt haben, die "closure" auf den Aufruf dieser Technik bestehen.

Der Grund, warum ich es "breaking" Schließungen nenne, ist, weil Sie das tun.

Der klassische Ort, wo man sieht diese in Lösungen für Verschlüsse in Schleifen ist:

var hellos = []; 

for (var i=0; i < 10; i++) { 
    hellos.push(
     (function(j){ 
      return 'hello ' + j 
     })(i) 
    ); 
} 

Das Problem wird durch einen Verschluss wird erstellt zwischen der äußeren Variable und Verweisen auf diese Variable in der inneren Funktion verursacht wird (technisch Die Variable wird eine "freie" Variable anstelle einer Schließung genannt, "Schließung" bezieht sich technisch auf den Mechanismus, der die Variable erfasst, aber in der js-Gemeinschaft haben wir beide Dinge als Schließungen bezeichnet. So Schließung ist die Ursache des Problems. Da das Problem durch eine Schließung verursacht wird, habe ich begonnen, die Lösung als "breaking the closure" zu bezeichnen.

Beachten Sie, dass obwohl einige Leute dies eine Schließung nennen und Sie googlen können für "js Schließung", um mehr über diese Technik zu lesen, ist es ironisch keine Schließung. Was es ist, ist einfach, wie Funktionen Argumente übergeben (es gibt eine ganze Seite Argument darüber, wie Javascript tatsächlich Argumente an Funktionen übergeben, die Sie hier lesen können: Why are objects' values captured inside function calls?). Javascript ist eine ziemlich strenge Pass-by-Value-Sprache, genau wie C eine strikte Pass-by-Value-Sprache ist (C kann NUR nach Wert übergeben werden).

Wenn Sie eine Referenz in js (Objekte, Arrays) übergeben, erhält die Funktion nicht die Originalreferenz, sondern eine Kopie der Referenz. Da es sich um eine Referenz handelt, weist es offensichtlich auf dasselbe Objekt wie die Originalreferenz hin, so dass es leicht ist, fälschlicherweise zu glauben, dass JavaScript durch Verweis weitergegeben wird. Wenn Sie jedoch versuchen, der übergebenen Referenz ein neues Objekt zuzuordnen, werden Sie feststellen, dass sich die ursprüngliche Referenz nicht ändert.Zum Beispiel:

function foo (x) { 
    x = [2,3]; 
} 

var y = [1,2]; 
foo(y); 
console.log(y) // prints [1,2] so foo() did not change y 

Es ist dieser Mechanismus, der zum Aufbrechen die Verbindung zwischen der äußeren Größe (in Ihrem Beispiel, das i wäre) verantwortlich ist und die innere Variable (_i in Ihrem Beispiel). Der Name dieses Mechanismus ist einfach Funktionsaufruf (gut, technisch ist es eine Untermenge von Funktionsaufruf - es ist, wie Argumente an Funktionsaufrufe übergeben werden).

So zu rekapitulieren:

  1. ich es persönlich nennen "breaking the closure"
  2. Manche Leute nennen es "closure" obwohl es keinen Verschluss ist (der Verschluss ist, was sie stattdessen vermeiden will).

Randbemerkung: Ich stelle fest, dass das ursprüngliche Beispiel über eine globale Variable ist aber in Javascript globale Variablen sind nur ein Spezialfall von Verschlüssen - Verschlüsse immer erstellt, wenn Sie eine Funktion definieren, es ist nur Wenn es keine äußere Funktion gibt, ist der äußere Bereich einfach der globale Bereich.

+0

Lustiger Hinweis: Ich habe angefangen, Go-Programmierer zu sehen, die diese Technik brauchen, was ein gutes Zeichen dafür ist, dass Menschen in anderen Programmiersprachen auch sind Es beginnt viel, Verschlusssysteme zu benutzen - was wiederum ein Zeichen dafür ist, dass sie asynchrone Programmierung machen – slebetman

0

Bei der Übergabe einer primitiven Variablen wie einer Zeichenfolge oder einer Zahl wird der Wert als Wert übergeben. Das bedeutet, dass alle Änderungen an dieser Variablen in der Funktion vollständig von allem außerhalb der Funktion abweichen.

Wenn die Variable im Bereich nicht deklariert ist, sucht sie den äußeren Bereich, bis sie gefunden wird, oder den Fensterbereich. Wenn nicht, wird die Variable global angezeigt.

Verwandte Themen