1. Zuerst müssen wir die variable Gültigkeitsbereichskette kennen
Es gibt zwei Arten von Variablenbereichen: globale Variablen und lokale Variablen. Variablen, die in keiner Funktion definiert sind, sind globale Variablen, und in einer Funktion definierte Variablen sind lokale Variablen. Beachten Sie, dass Sie das Schlüsselwort var verwenden müssen, wenn Sie Variablen innerhalb einer Funktion definieren.
Jeder Codeabschnitt in JavaScript verfügt über eine zugehörige Bereichskette. Diese Bereichskette ist eine Liste von Objekten oder eine verknüpfte Liste, die die Variablen im „Bereich“ dieses Codeabschnitts definiert. Der Bereich des Codes der obersten Ebene besteht aus globalen Variablen. Die Bereichskette, die keine verschachtelten Funktionen enthält, besteht aus zwei Objekten: eines ist das Objekt der definierten Funktionsparameter und lokalen Variablen und das andere ist das globale Variablenobjekt Umfang der verschachtelten Funktion Die Kette besteht aus drei Objekten: Funktionsparameter und lokale Variablen – Parameter externer Funktionen und lokale Variablen – globale Variablen. Funktionen können auf Objekte in der Bereichskette zugreifen, sodass Funktionen auf globale Variablen zugreifen können, aber nicht umgekehrt, d. h. auf lokale Variablen innerhalb einer Funktion kann nicht von außerhalb der Funktion zugegriffen werden.
var a=1; function wai(){ alert(a); var m=10; n=20; } wai(); //=> 1; 函数内部可以访问全局变量 alert(m); //=> error; 外部访问函数局部变量报错 alert(n); //=> 20; 函数内部定义的变量未使用var关键字,所以是全局变量,外部可以访问
2. So lesen Sie lokale Variablen extern
Manchmal müssen wir von außen auf lokale Variablen innerhalb einer Funktion zugreifen. In diesem Fall müssen wir einen Workaround verwenden. Wir verwenden die Eigenschaften des JavaScript-Variablenbereichs, um Unterfunktionen innerhalb der Funktion zu definieren, und die Unterfunktion kann auf die Variablen in der übergeordneten Funktion
zugreifenfunction wai(){ var m=10; function nei(){ alert(m); } return nei; } var f = wai(); nei(); //=> error; nei()函数是一个局部变量,在外部不能访问 f(); //=> 10;
3. Schließung
Die nei()-Funktion im vorherigen Code ist ein Abschluss. Wie aus dem Obigen hervorgeht, ist ein Abschluss eine Funktion, die die lokalen Variablen innerhalb der Funktion lesen kann Es kann als die Funktion innerhalb und außerhalb der Funktion betrachtet werden. Brücken, die das Äußere miteinander verbinden.
Verschlüsse haben zwei Funktionen:
Zuerst können Sie, wie bereits erwähnt, die Variablen innerhalb der Funktion lesen
Zweitens können diese lokalen Variablen im Speicher gespeichert werden, um die gemeinsame Nutzung variabler Daten zu realisieren
function wai(){ var m=99; function nei(){ alert(m); m++; } return nei; } var f= wai(); f(); //=> 99; f(); //=> 100; f(); //=> 101;
Im obigen Beispiel wird die Variable m im Speicher gespeichert, wenn die Funktion wai() ausgeführt wird. Der Wert von m kann durch Ausführen von f() gelesen werden, direkte Warnung(m) jedoch nicht!
Wir können auch Parameter an die Abschlussfunktion übergeben. Wie im folgenden Beispiel gezeigt, wird eine anonyme Funktion definiert und eine Abschlussfunktion zurückgegeben. Die Funktion fügt die übergebenen Parameter zur lokalen Variablen i in der anonymen Funktion hinzu ich erhöhe;
var wai=(function(){ var i=0; return function(num){ num+=i; alert(num); i++; } })(); wai(1);//1 wai(2);//3 wai(3);//5
Um Abschlüsse besser zu verstehen, schauen wir uns das folgende Beispiel an:
Jetzt möchte ich eine Funktion definieren, die ein Array zurückgibt, und jedes Element des Arrays ist eine Funktion, und jede Funktion zeigt den entsprechenden Indexwert an
Wir könnten so schreiben
function box(){ var arr=[]; for(i=0;i<5;i++){ arr[i]=function(){return i;} } return arr; } var a=box(); alert(a); //=>包含五个函数体的数组 alert(a[0]()); //=> 5; alert(a[1]()); //=> 5;
Der obige Code stellt fest, dass alle Popups 5 sind, nicht wie erwartet 0,1,2,3,4. Dies liegt daran, dass ich auch eine lokale Variable ist, die im Speicher vorhanden ist ]() Zu diesem Zeitpunkt beträgt der Wert von i bereits 5 und der Wert von i steigt während des gesamten laufenden Prozesses der Funktion box() weiter an.
Lösung: Umsetzung von Schließungen
function box(){ var arr=[]; for(var i=0;i<5;i++){ arr[i]=(function(num){ return function(){return num;} })(i); } return arr; } var arr=box(); for(var i=0;i<5;i++){ alert(arr[i]());//0,1,2,3,4 }
4. Dinge, die bei der Verwendung von Verschlüssen zu beachten sind
1) Da Schließungen dazu führen, dass die Variablen in der Funktion im Speicher gespeichert werden, was viel Speicher verbraucht, können Schließungen nicht missbraucht werden, da dies sonst zu Leistungsproblemen auf der Webseite führen und zu Speicherverlusten führen kann IE. Die Lösung besteht darin, alle nicht verwendeten lokalen Variablen zu löschen, bevor die Funktion beendet wird.
2) Der Abschluss ändert den Wert der Variablen innerhalb der übergeordneten Funktion außerhalb der übergeordneten Funktion. Wenn Sie daher die übergeordnete Funktion als Objekt, den Abschluss als öffentliche Methode und die internen Variablen als privaten Wert verwenden, müssen Sie darauf achten, die Variablenwerte der übergeordneten Funktion nicht zu ändern.
5. Hier sind einige Fragen zu Schließungen
Wenn Sie die Ergebnisse des folgenden Codes verstehen können, sollten Sie den Funktionsmechanismus von Schließungen verstehen.
Js-Code
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; //=>嵌套函数的this为全局变量或undefined,不会继承父函数的this }; } }; alert(object.getNameFunc()()); //The Window
Der Grund, warum die obige Ausgabe „Das Fenster“ ist, liegt darin, dass diese in der verschachtelten Funktion dies nicht von der übergeordneten Funktion erbt und ihr Wert eine globale Variable oder undefiniert ist (unter ECMAScript5), sodass der Name zurückgegeben wird Variable des globalen Objekts. Wenn Sie möchten, dass das Namensattribut des Objekts zurückgegeben wird, lautet der Code wie folgt:
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var cur=this; return function(){ return cur.name; }; } }; alert(object.getNameFunc()()); //=》My Object
Der obige Code weist das übergeordnete Funktionsobjekt der Variablen cur zu, und seine verschachtelte Funktion kann über die Variable cur auf seine Eigenschaften zugreifen
--------------------------------- --- ------------------ --- -----
Beispiel für einen JavaScript-Abschluss
function outerFun() { var a=0; function innerFun() { a++; alert(a); } } innerFun(); //=>error
Der obige Code ist falsch. Der Gültigkeitsbereich von innerFun() liegt innerhalb von OuterFun() und es ist falsch, ihn außerhalb von OuterFun() aufzurufen.
wird wie folgt geändert, was eine Schließung darstellt:
Js-Code
function outerFun() { var a=0; function innerFun() { a++; alert(a); } return innerFun; //注意这里 } var obj=outerFun(); obj(); //结果为1 obj(); //结果为2 var obj2=outerFun(); obj2(); //结果为1 obj2(); //结果为2
什么是闭包:
当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们.
--------------------------------------------------------------------------------------------------------
再来看一个例子
Js代码
function outerFun() { var a =0; alert(a); } var a=4; outerFun(); //=> 0 alert(a); //=> 4
结果是 0,4 . 因为在函数内部使用了var关键字 维护a的作用域在outFun()内部.
再看下面的代码:
Js代码
function outerFun() { //没有var a =0; alert(a); } var a=4; outerFun(); //=> 0 alert(a); //=> 0
结果为 0,0 真是奇怪,为什么呢?
作用域链是描述一种路径的术语,沿着该路径可以确定变量的值 .当执行a=0时,因为没有使用var关键字,因此赋值操作会沿着作用域链到var a=4; 并改变其值.