Schließung (Abschluss) ist eine sehr wichtige Schwelle für die Beherrschung von Javascript vom Anfänger bis zum Tiefgang. Es ist eine Schwierigkeit der Javascript-Sprache und auch ihre Eigenschaft für viele fortgeschrittene Anwendungen Alles hängt vom Abschluss ab. Schreiben Sie unten meine Studiennotizen auf ~
Ausführliche Erklärung des JavaScript-Abschlusses (Closure)
Ausführliche Erklärung von JavaScript This
Eine ausführliche Einführung in die Prototypenkette und Vererbung von JavaScript
In der Frontend-Programmierung ist die Verwendung von Abschlüssen sehr verbreitet. Wir verwenden Abschlüsse oft absichtlich oder unabsichtlich, direkt oder indirekt. Schließungen können die Datenübertragung flexibler machen (z. B. die Verarbeitung einiger Klickereignisse)
!function() { var localData = "localData here"; document.addEventListener('click', //处理点击事件时用到了外部局部变量,比如这里的localData function(){ console.log(localData); }); }();
Ein weiteres Beispiel ist das Folgende: (Ist es nicht sehr freundlich~~)
!function() { var localData = "localData here"; var url = "http://www.baidu.com/"; $.ajax({ url : url, success : function() { // do sth... console.log(localData); } }); }();
Lass uns Schauen Sie sich ein anderes Beispiel an. Diese Situation nennen wir normalerweise Abschluss
function outer() { var localVal = 30; return function(){ return localVal; } } var func = outer(); func(); // 30
In diesem Beispiel wird äußere() aufgerufen, um die anonyme Funktion zurückzugeben Funktion() In dieser anonymen Funktion ist dies die lokale Variable Auf den LocalVal von Outer () kann zugegriffen werden. Nachdem der Aufruf von Outer () abgeschlossen ist, kann beim erneuten Aufruf von Func () weiterhin auf die lokale Variable LocalVal von Outer () zugegriffen werden
Abschluss unterscheidet sich von der allgemeinen Funktion. Eine Funktion, die es einer Funktion ermöglicht, weiterhin auf nicht-lokale Variablen zuzugreifen, wenn sie außerhalb des unmittelbaren lexikalischen Bereichs aufgerufen wird. – Wikipedia
Ein Abschluss ist eine Funktion, die die internen Variablen anderer Funktionen lesen kann. – Ruan Yifeng
Da in der Javascript-Sprache nur Unterfunktionen innerhalb der Funktion lokale Variablen lesen können, können Abschlüsse einfach als „in einer Funktion definierte Funktionen“ verstanden werden.
Im Wesentlichen ist der Abschluss also eine Brücke, die das Innere einer Funktion mit der Außenseite der Funktion verbindet
Dieser Teil wurde aus diesem Blog reproduziert Beitrag
Verschlüsse können an vielen Stellen eingesetzt werden. Seine größten Verwendungszwecke bestehen zum einen darin, die Variablen innerhalb der Funktion zu lesen, und zum anderen darin, die Werte dieser Variablen im Speicher zu halten.
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
In diesem Code ist das Ergebnis tatsächlich die Abschlussfunktion f2. Es wurde zweimal ausgeführt, beim ersten Mal war der Wert 999, beim zweiten Mal war der Wert 1000. Dies beweist, dass die lokale Variable n in der Funktion f1 immer im Speicher gespeichert ist und nach dem Aufruf von f1 nicht automatisch gelöscht wird.
Warum passiert das? Der Grund dafür ist, dass f1 die übergeordnete Funktion von f2 ist und f2 einer globalen Variablen zugewiesen ist, wodurch f2 immer im Speicher bleibt und die Existenz von f2 von f1 abhängt, sodass f1 immer im Speicher ist und nicht gelöscht wird Nach Abschluss des Anrufs wird es vom Garbage-Collection-Mechanismus recycelt.
Eine weitere erwähnenswerte Sache in diesem Code ist die Zeile „nAdd=function(){n+=1}“. Erstens wird das Schlüsselwort var nicht vor nAdd verwendet, daher ist nAdd eher eine globale Variable als lokale Variablen. Zweitens ist der Wert von nAdd eine anonyme Funktion, und diese anonyme Funktion selbst ist auch ein Abschluss, sodass nAdd einem Setter entspricht, der lokale Variablen innerhalb der Funktion außerhalb der Funktion bearbeiten kann.
(function() { var _userId = 23492; var _typeId = 'item'; var export = {}; function converter(userId) { return +userId; } export.getUserId = function() { return converter(_userId); } export.getTypeId = function() { return _typeId; } window.export = export; //通过此方式输出 }()); export.getUserId(); // 23492 export.getTypeId(); // item export._userId; // undefined export._typeId; // undefined export.converter; // undefined
Die Verwendung der Eigenschaften von Verschlüssen ermöglicht es uns, einige komplexe Funktionen zu kapseln. Logischerweise In diesem Beispiel werden die Methoden beim Export (getUserId, getTypeId) aufgerufen, um indirekt auf die privaten Variablen in der Funktion zuzugreifen, aber _userId kann nicht durch direkten Aufruf von export._userId abgerufen werden. Dies ist auch eine häufig verwendete Funktion in Node~
Im folgenden Fall: Wir addieren 3 p, die Werte sind aaa, bbb, ccc. Was wir erreichen möchten, ist, auf aaa zu klicken, um 1 auszugeben, auf bbb, um 2 auszugeben, und auf ccc, um 3 auszugeben
document.body.innerHTML = "<p id=p1>aaa</p>" + "<p id=p2>bbb</p><p id=p3>ccc</p>"; for (var i = 1; i < 4; i++) { document.getElementById('p' + i). addEventListener('click', function() { alert(i); // all are 4! }); }
Daher sind alle Klicks auf aaa, bbb oder ccc alarm(4)~~
Das Problem besteht darin, dass der Wert von i bei der Initialisierung bereits 4 ist abgeschlossen
Um das zu erreichen, was wir wollen, klicken Sie auf aaa, um 1 auszugeben, klicken Sie auf bbb, um 2 auszugeben, und klicken Sie auf ccc, um 3 auszugeben. Wir müssen die Abschlusstechnik verwenden und sie mit umschließen Eine anonyme Funktion, die sofort ausgeführt wird. Der Wert von warning(i) wird jedes Mal von i in der Abschlussumgebung übernommen. Dadurch wird 1, 2 und 3 aus der Zuweisung i jeder Schleife < ausgegeben 🎜>
document.body.innerHTML = "<p id=p1>aaa</p>" + "<p id=p2>bbb</p>" + "<p id=p3>ccc</p>"; for (var i = 1; i < 4; i++) { !function(i){ //②再用这个参数i,到getElementById()中引用 document.getElementById('p' + i). addEventListener('click', function() { alert(i); // 1,2,3 }); }(i); //①把遍历的1,2,3的值传到匿名函数里面 }
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()());
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());