Heim >Web-Frontend >js-Tutorial >Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung
JavascriptDie Spalte stellt den Speicherverwaltungsmechanismus und die Überprüfung vor
Empfohlen (kostenlos): JavaScript (Video)
Scope
JavaScript-Variablen haben einen begrenzten Gültigkeitsbereich, wenn Wenn es den Gültigkeitsbereich überschreitet, kann die Variable nicht mehr verwendet werden:
und den Variablenbereich Abhängig von der Deklarationsmethode werden auch unterschiedliche Bereiche generiert:
var
Deklariert: Bereich in var
声明:作用域在 函数 中let
、const
声明:作用域在 {}
中var 声明的变量
在函数内声明的变量其作用域会被限制在该函数的调用栈中,在外部无法直接得到该作用域内的变量。下面的例子中, fn
函数内的变量在全局下是没有办法查看的。
function fn() { var a = 1; } fn(); console.log(a); // 无法得到 fn 函数內的 a 变量
所以常用 "立即函数" 来限制变量的作用域,主要是避免全局变量的产生。
(function() { var b = 1; })(); console.log(b); // 无法得到 fn 函数內的 b 变量
let、const 声明的变量
ES6 之后所新增的let
、const
作用域则与过去不同,改用 {}
作为作限制用域的方式,这让 for 循环及部分语法避免产生多余的变量来影响作用域。
与 var
不同的是 const
所定义的变量作用域被限制在 {}
中。所以这个例子中的变量 c
可在外部得到值,d
则无法取到。
{ var c = 1; const d = 1; } console.log(c); // 1 console.log(d); // Uncaught ReferenceError: d is not defined,无法取到变量 d
内存管理机制
每当我们新增一个变量时,在内存中就会占用一个位置来保存它的值,以便在程序后续运行时可以多次使用。
下面的代码会在内存中开辟一个 a
的空间来存储数字 1 的值。
var a = 1
流程如下:
a
,不过这时还没有赋值(原因可参考:Hoisting)a
赋值。所有的变量都会占用内存空间,除此之外对象、数组的属性以及函数参数等也会用相同的概念进行占用。调用一个函数时,每一个函数的作用域也都会反复的进行内存占用。随着应用程序越来越复杂的情况下,如果持续的占用内存而没有进行适当的释放,那么内存可能会被耗尽。
JavaScript 引擎具有内存回收的机制,会释放不再使用的变量内存,其基本概念为:当没有任何的引用指向它时就会释放内存。
来自MDN:collectible if there are zero references pointing to it.
内存释放的验证
下面用一个例子来说明及验证内存释放的机制,首先用一段函数来产生一个非常长的字符串,长字符串会占用大量的内存空间。
在调用 randomString
函数后会返回一个很长的字串:
function randomString(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i <h4>案例一:使变量维持在可引用的状态(不会释放内存)</h4><p>定义一个全局变量 <code>demoData</code>,这个变量会持续维持可被引用的状态。</p><pre class="brush:php;toolbar:false">var demoData = []; // 全局变量 function getData() { for (let i = 0; i <p>执行这段代码后,进入 Chrome DevTools 中的 Memory 页,这个功能可以得到当前页面所占用的内存状况。接下来点击 "Take snapshot" 按钮。</p><p><img src="https://img.php.cn/upload/image/189/951/684/1609320713198525.png" title="1609320713198525.png" alt="Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung"></p><p>可以看到目前执行完这段代码后占用了 6.2MB 的内存空间(注意:任何浏览器环境和插件都会影响所占用的内存状态)。</p><p><img src="https://img.php.cn/upload/image/742/181/269/1609320718742831.png" title="1609320718742831.png" alt="Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung"></p><h4>案例二:使变量无法再次被引用(执行后释放内存)</h4><p>限制变量的作用域,使变量无法再被外部引用。</p><p>此段代码依然会执行这个函数,也会将值赋值给变量,但外部无法再次引用 <code>demoData</code>function</p>🎜🎜<code>let</code>, <code> const</code>-Deklaration: Der Bereich liegt in <code>{}</code> 🎜🎜🎜🎜Var-Variablen, die in 🎜🎜🎜Variablen deklariert wurden, die innerhalb der Funktion deklariert wurden, sind auf diesen Bereich im Aufrufstapel einer Funktion beschränkt Variablen in diesem Bereich können nicht direkt von außen abgerufen werden. Im folgenden Beispiel können die Variablen innerhalb der Funktion <code>fn</code> nicht global angezeigt werden. 🎜<pre class="brush:php;toolbar:false">function getData() { var demoData = []; // 局部变量 for (var i = 0; i 🎜Daher werden „unmittelbare Funktionen“ häufig verwendet, um den Umfang von Variablen einzuschränken, hauptsächlich um die Generierung globaler Variablen zu vermeiden. 🎜rrreee🎜🎜let- und const-deklarierte Variablen🎜🎜🎜Die neu hinzugefügten <code>let</code>- und <code>const</code>-Bereiche nach ES6 unterscheiden sich von der Vergangenheit und verwenden stattdessen <code>{}. </code> Um den Bereich einzuschränken, ermöglicht dies Schleifen und einige Syntaxen, um die Generierung redundanter Variablen zu vermeiden, die sich auf den Bereich auswirken. 🎜🎜Der Unterschied zu <code>var</code> besteht darin, dass der Umfang der durch <code>const</code> definierten Variablen auf <code>{}</code> beschränkt ist. Die Variable <code>c</code> in diesem Beispiel kann also ihren Wert extern erhalten, <code>d</code> jedoch nicht. 🎜rrreee🎜🎜Speicherverwaltungsmechanismus🎜🎜🎜Jedes Mal, wenn wir eine Variable hinzufügen, belegt sie einen Platz im Speicher, um ihren Wert zu speichern, sodass sie bei späterer Programmausführung mehrmals verwendet werden kann. 🎜🎜Der folgende Code öffnet einen <code>a</code>-Bereich im Speicher, um den Wert der Zahl 1 zu speichern. 🎜rrreee🎜Der Prozess ist wie folgt: 🎜<ol>🎜Öffnen Sie einen Speicherplatz, um die Variable <code>a</code> zu speichern, aber es ist noch kein Wert zugewiesen (den Grund finden Sie unter: Heben) 🎜</ol>🎜<img src="https://img.php.cn/upload/image/255/233/570/1609320703253175.png" title="1609320703253175.png" alt="Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung">🎜<ol>🎜 ist <code> eine</code>-Aufgabe. 🎜</ol>🎜<img src="https://img.php.cn/upload/image/904/544/616/1609320708403601.png" title="1609320708403601.png" alt="2a2c245dd1d9d9e210bd692708380d7.p ng">🎜🎜Alle Variablen belegen Speicherplatz. Darüber hinaus belegen Objekte, Array-Attribute und Funktionsparameter nach demselben Konzept ebenfalls Speicherplatz. Wenn eine Funktion aufgerufen wird, belegt der Umfang jeder Funktion auch wiederholt Speicher. Wenn Anwendungen immer komplexer werden, kann der Speicher erschöpft sein, wenn er weiterhin Speicher belegt, ohne ihn ordnungsgemäß freizugeben. 🎜🎜Die JavaScript-Engine verfügt über einen Speicherrecyclingmechanismus, der nicht mehr verwendeten Variablenspeicher freigibt. Das Grundkonzept ist: Der Speicher wird freigegeben, wenn keine Referenzen darauf verweisen. 🎜<blockquote>Von MDN: sammelbar, wenn keine Referenzen darauf verweisen.</blockquote>🎜🎜Überprüfung der Speicherfreigabe🎜🎜🎜Im Folgenden wird ein Beispiel verwendet, um den Mechanismus der Speicherfreigabe zu veranschaulichen und zu überprüfen. Verwenden Sie zunächst eine Funktion um eine sehr lange Zeichenfolge zu generieren. Lange Zeichenfolgen beanspruchen viel Speicherplatz. 🎜🎜Nach dem Aufruf der Funktion <code>randomString</code> wird ein sehr langer String zurückgegeben: 🎜rrreee<h4>Fall 1: Behalten Sie die Variable in einem referenzierbaren Zustand (es wird kein Speicher freigegeben)</h4>🎜 Definieren Sie eine globale Variable <code>demoData</code>, auf die weiterhin verwiesen wird. 🎜rrreee🎜Nachdem Sie diesen Code ausgeführt haben, rufen Sie die Speicherseite in Chrome DevTools auf. Diese Funktion kann den von der aktuellen Seite belegten Speicherstatus abrufen. Klicken Sie anschließend auf die Schaltfläche „Schnappschuss erstellen“. 🎜🎜<img src="https://img.php.cn/upload/image/189/951/684/1609320713198525.png" title="1609320713198525.png" alt="Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung"> 🎜🎜Ja Es ist ersichtlich, dass nach der Ausführung dieses Codes 6,2 MB Speicherplatz belegt sind (Hinweis: Alle Browserumgebungen und Plug-Ins wirken sich auf den belegten Speicherstatus aus). 🎜🎜<img src="https://img.php.cn/upload/image/742/181/269/1609320718742831.png" title="1609320718742831.png" alt="Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung"> 🎜<h4>Fall 2: Machen Sie die Variable nicht mehr referenzierbar (geben Sie Speicher nach der Ausführung frei)</h4>🎜Beschränken Sie den Gültigkeitsbereich der Variablen, sodass die Variable nicht mehr extern referenziert werden kann. 🎜🎜Dieser Code führt weiterhin die Funktion aus und weist den Wert der Variablen zu, aber der Wert von <code>demoData</code> kann nicht erneut extern referenziert werden. 🎜<pre class="brush:php;toolbar:false">function getData() { var demoData = []; // 局部变量 for (var i = 0; i <p>然后回到 Memory 页点击 "Take snapshot" 重新取得内存的状态,接下来会得到与前面不同的结果,这次只占用了 1.2MB 的内存(其中 5MB 被释放掉了)</p><p><img src="https://img.php.cn/upload/image/148/641/618/1609320723163241.png" title="1609320723163241.png" alt="Erläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung"></p><p><strong>总结</strong></p><p>通过前面的例子,我们知道了作用域以及内存之间的关系,而内存管理也是前端打工人必须要掌握的知识(除了控制内存的使用大小,还需在必要时保留而不被释放)。</p>
Das obige ist der detaillierte Inhalt vonErläutern Sie den JS-Speicherverwaltungsmechanismus und die Überprüfung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!