Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung von JavaScript-Variablen, Umfang und Speicher

Detaillierte Erläuterung von JavaScript-Variablen, Umfang und Speicher

黄舟
黄舟Original
2017-03-04 16:02:451239Durchsuche

Die Grundtypwerte sind: undefined,NUll,Boolean,Number和String Diese Typen belegen einen festen Speicherplatz im Speicher. Ihre Werte werden im Stapelbereich gespeichert und wir greifen nach Wert auf sie zu.

(1) Werttyp: numerischer Wert, boolescher Wert, null, undefiniert.
(2) Referenztyp: Objekt, Array, Funktion.

Wenn der zugewiesene Wert ein Referenztyp ist, muss für diesen Wert Platz im Heap-Speicher reserviert werden. Da die Größe solcher Werte nicht festgelegt ist (Objekte haben viele Eigenschaften und Methoden), können sie nicht im Stapelspeicher gespeichert werden. Die Größe der Speicheradresse ist jedoch fest, sodass die Speicheradresse im Stapelspeicher gespeichert werden kann.

<script type="text/javascript”>
var box = new Object();  //创建一个引用类型
var box = "trigkit4";   //基本类型值是字符串
box.age = 21;    //基本类型值添加属性很怪异,因为只有对象才可以添加属性。
alert(box.age);  //不是引用类型,无法输出;
</script>

Kurz gesagt, der Heap-Speicher speichert Referenzwerte und der Stapelspeicher speichert feste Typwerte. Eine „Referenz“ ist ein Hinweis auf den tatsächlichen Standort eines Objekts.

Hier ist zu beachten, dass die Referenz auf ein bestimmtes Objekt verweist, nicht auf eine andere Referenz.

Die Objekte hier können String-Objekte, numerische Objekte, Array-Objekte usw. sein.

<script type="text/javascript">
    var man = new Object();//man指向了栈内存的空间地址
    man.name = "Jack";
    var man2 = man;//man2获得了man的指向地址

    alert(man2.name);//两个都弹出Jack
    alert(man.name);
</script>

Variablenwerte kopieren

Schau Nochmals das folgende Beispiel:

<script type="text/javascript">
    var man = new Object();//man指向了栈内存的空间地址
    man.name = "Jack";
    var man2 = man;//man2获得了man的指向地址

    man2.name = "ming";//因为他们都指向同一个object,同一个name,不管修改谁,大家都修改了
    alert(man2.name);//两个都弹出ming
    alert(man.name);
</script>

Aus dem oben Gesagten kann geschlossen werden, dass sich Basistypen und Referenztypen auch hinsichtlich des Kopierens von Variablen unterscheiden. Basistypen kopieren den Wert selbst, während Referenztypen die Adresse kopieren .

Parameter übergeben

In ECMAScript werden die Parameter aller Funktionen als Wert übergeben,

<script type="text/javascript">
     function box(num){      //按值传递
         num+=10;
         return num;
     }

     var num = 10;
     var result = box(num);
     alert(result);  //如果是按引用传递,那么函数里的num会成为类似全局变量,把外面的number替换掉
     alert(num);    //也就是说,最后应该输出20(这里输出10)
</script>

js werden nicht als Referenz übergeben, wenn eine Übergabe vorliegt Referenz Wenn ja, dann sind die Variablen innerhalb der Funktion globale Variablen und können auch extern aufgerufen werden. Aber das ist offensichtlich unmöglich.

Ausführungsumgebung und -umfang

Ausführungsumgebung ist eines der wichtigsten Konzepte in javascript. Die Ausführungsumgebung definiert, dass Variablen oder Funktionen Zugriff auf andere Daten haben.

Die globale Ausführungsumgebung ist die peripherste Ausführungsumgebung. In einem Webbrowser ist die globale Ausführungsumgebung das window-Objekt. Daher werden alle globalen Variablenfunktionen als Attribute und Methoden von window erstellt .

<script type="text/javascript">
      var name = "Jack";           //定义全局变量
      function setName(){
          return "trigkit4";
      }

      alert(window.name);        //全局变量,最外围,属于window属性
      alert(window.setName());  //全局函数,最外围,属于window方法
</script>

Wenn der Code in der Ausführungsumgebung ausgeführt wird, wird die Umgebung zerstört und die darin gespeicherten Variablen und Funktionen werden ebenfalls zerstört. Wenn es sich um eine globale Umgebung handelt, muss sie nach Abschluss aller Programme abgeschlossen werden wurden ausgeführt oder die Webseite wurde vernichtet.

Entfernen Sie die lokale Variable von var

<script type="text/javascript">
      var name = "Jack";
      function setName(){
          name = "trigkit4";   //去掉var变成了全局变量
      }

      setName();
      alert(name);//弹出trigkit4
</script>

Durch die Übergabe von Parametern ist es auch eine lokale Variable

<script type="text/javascript">
      var name = "Jack";
      function setName(name){    //通过传参,也是局部变量
          alert(name);
      }

      setName("trigkit4");//弹出trigkit4
      alert(name);//弹出Jack
</script>

Der Funktionskörper enthält auch eine Funktion, und zwar nur Diese Funktion kann auf die internen Layer-Funktionen zugreifen.

<script type="text/javascript">
     var name = "Jack";
      function setName(){
          function setYear(){    //setYear()方法的作用域在setName()内
              return 21;
          }
      }
      alert(setYear());//无法访问,出错 
</script>

kann über die folgenden Methoden aufgerufen werden:

<script type="text/javascript">
     var name = "Jack";
      function setName(){
          function setYear(){    //setYear()方法的作用域在setName()内
              return 21;
          }
          return setYear();
      }
      alert(setName()); //弹出21
</script>

Ein weiteres Bereichsbeispiel:

<script type="text/javascript">
     var name = "Jack";
      function setName(){
          function setYear(){    //setYear()方法的作用域在setName()内
              var b = "hi";     //变量b的作用域在setYear()内
              return 21;
          }
          alert(b);//无法访问 
      }
</script>

Wenn die Wenn Code in einer Umgebung ausgeführt wird, wird etwas namens 作用域链 gebildet. Sein Zweck besteht darin, einen ordnungsgemäßen Zugriff auf Variablen und Funktionen sicherzustellen, die über Zugriffsrechte in der Ausführungsumgebung verfügen (bezogen auf den Zugriff entsprechend der Regelebene). der Bereichskette. Es ist das variable Objekt der Ausführungsumgebung.

Geltungsbereich

Die Variable wird nicht innerhalb der Funktion deklariert oder ohne var deklariert, was eine globale Variable ist und einen globalen Gültigkeitsbereich hat. windowAlle Eigenschaften des Objekts haben einen globalen Gültigkeitsbereich; Es kann überall im Code darauf zugegriffen werden. Variablen, die innerhalb einer Funktion deklariert und mit var geändert werden, können nur innerhalb des Funktionskörpers verwendet werden immer noch lokale Variablen. var

Es gibt keinen Gültigkeitsbereich auf Blockebene

// if语句:

<script type="text/javascript">
if(true){                        //if语句的花括号没有作用域的功能。

var box = "trigkit4";
}
alert(box);//弹出 trigkit4
</script>
Dasselbe gilt für die for-Schleifenanweisung.

Variablenabfrage

Bei der Variablenabfrage ist der Zugriff auf lokale Variablen schneller als auf globale Variablen, sodass keine Suche in der Bereichskette erforderlich ist.

Das folgende Beispiel:

<script type="text/javascript">
     var name = "Jack";
      function setName(){
           var name = "trigkit4";
           return name;  //从底层向上搜索变量
    }
    alert(setName());      
</script>
Jede Umgebung kann in der Bereichskette nach oben durchsucht werden, um Variablen- und Funktionsnamen abzufragen, es kann jedoch keine Umgebung eingegeben werden, indem in der Bereichskette nach unten gesucht wird. Eine andere Ausführungsumgebung. Wenn Sie hier

entfernen, wird „Jack“ angezeigt. var name = "trigkit4"

Speicherprobleme

verfügt über einen automatischen Speicherbereinigungsmechanismus. Sobald die Daten nicht mehr verwendet werden, kann dies geschehen auf „null“ gesetzt werden, um die Referenz freizugeben javascript

Zirkelreferenz

Ein sehr einfaches Beispiel: Ein DOM-Objekt wird von einem

-Objekt referenziert und verweist gleichzeitig auf dasselbe oder Wenn Sie ein anderes Javascript-Objekt verwenden, kann dieses Javascript-Objekt zu Speicherverlusten führen. Der Verweis auf dieses DOM-Objekt wird vom Garbage Collector nicht erfasst, wenn das Skript stoppt. Um den Zirkelverweis zu unterbrechen, muss dem Objekt, das auf das DOM-Element verweist, oder der Referenz auf das DOM-Objekt der Wert DOM zugewiesen werden. null

Abschluss

Wenn eine Variable außerhalb des Abschlusses in den Abschluss eingeführt wird, kann das Objekt am Ende des Abschlusses nicht durch Garbage Collection (GC) gesammelt werden.

var a = function() {
  var largeStr = new Array(1000000).join(&#39;x&#39;);
  return function() {
    return largeStr;
  }
}();
DOM-Leck

Wenn die ursprüngliche COM entfernt wird, kann die Referenz auf den untergeordneten Knoten nicht wiederverwendet werden, es sei denn, sie wird entfernt.

var select = document.querySelector;
var treeRef = select(&#39;#tree&#39;);

//在COM树中leafRef是treeFre的一个子结点
var leafRef = select(&#39;#leaf&#39;); 
var body = select(&#39;body&#39;);

body.removeChild(treeRef);

//#tree不能被回收入,因为treeRef还在
//解决方法:
treeRef = null;

//tree还不能被回收,因为叶子结果leafRef还在
leafRef = null;

//现在#tree可以被释放了。
Timer-Timer-Lecks

Timer sind auch ein häufiger Ort, an dem Speicherlecks auftreten:

for (var i = 0; i < 90000; i++) {
  var buggyObject = {
    callAgain: function() {
      var ref = this;
      var val = setTimeout(function() {
        ref.callAgain();
      }, 90000);
    }
  }

  buggyObject.callAgain();
  //虽然你想回收但是timer还在
  buggyObject = null;
}

调试内存

Chrome自带的内存调试工具可以很方便地查看内存使用情况和内存泄露,在 Timeline -> Memory 点击record即可。

以上就是JavaScript 变量、作用域及内存详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn