Maison  >  Article  >  interface Web  >  Explication détaillée des variables JavaScript, de la portée et de la mémoire

Explication détaillée des variables JavaScript, de la portée et de la mémoire

黄舟
黄舟original
2017-03-04 16:02:451213parcourir

Les valeurs de type de base sont : undefined,NUll,Boolean,Number和String Ces types occupent un espace de taille fixe dans la mémoire. Leurs valeurs sont stockées dans l'espace de la pile et nous y accédons par valeur.

(1) Type de valeur : valeur numérique, valeur booléenne, nulle, non définie.
(2) Type de référence : objet, tableau, fonction.

Si la valeur attribuée est un type référence, un espace doit être alloué pour cette valeur dans la mémoire tas. Étant donné que la taille de ces valeurs n'est pas fixe (les objets ont de nombreuses propriétés et méthodes), elles ne peuvent pas être enregistrées dans la mémoire de la pile. Mais la taille de l'adresse mémoire est fixe, de sorte que l'adresse mémoire peut être enregistrée dans la mémoire de la pile.

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

En bref, la mémoire tas stocke les valeurs de référence et la mémoire pile stocke les valeurs de type fixe. Une « référence » est un pointeur vers l’emplacement réel d’un objet.

Il convient de noter ici que la référence pointe vers un objet spécifique, pas une autre référence.

Les objets ici peuvent être des objets chaîne, des objets numériques, des objets tableau, etc.

<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>

Copier les valeurs des variables

Regardez encore une fois L'exemple suivant :

<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>

De ce qui précède, nous pouvons conclure que les types de base et les types de référence sont également différents en termes de copie de variables. Les types de base copient la valeur elle-même, tandis que les types de référence copient l'adresse. .

Passer des paramètres

Dans ECMAScript, les paramètres de toutes les fonctions sont passés par valeur,

<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 ne sont pas passés par référence, s'il y a passage par référence Si tel est le cas, alors les variables de la fonction seront des variables globales et seront également accessibles en externe. Mais c'est évidemment impossible.

Environnement et portée d'exécution

L'environnement d'exécution est l'un des concepts les plus importants de javascript L'environnement d'exécution définit que les variables ou les fonctions ont accès à d'autres données.

L'environnement d'exécution global est l'environnement d'exécution le plus périphérique. Dans un navigateur Web, l'environnement d'exécution global est l'objet window. Par conséquent, toutes les fonctions de variables globales sont créées en tant qu'attributs et méthodes de window. .

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

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

Lorsque le code dans l'environnement d'exécution est exécuté, l'environnement est détruit, et les variables et fonctions qui y sont enregistrées sont également détruites. S'il s'agit d'un environnement global, il doit être terminé après tous les programmes. ont été exécutés ou la page Web a été complétée sera détruite.

Supprimer la variable locale de var

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

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

En passant des paramètres, c'est aussi une variable locale

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

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

Le corps de la fonction contient également une fonction, et seulement cette fonction peut accéder à celle interne. Les fonctions de couche

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

sont accessibles via les méthodes suivantes :

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

Un autre exemple de portée :

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

Lorsque le le code est exécuté dans un environnement Quand , quelque chose appelé 作用域链 sera formé. Son but est d'assurer un accès ordonné aux variables et aux fonctions qui ont des droits d'accès dans l'environnement d'exécution (faisant référence à l'accès selon le niveau de règle). de la chaîne de portée, C'est l'objet variable de l'environnement d'exécution.

Portée

La variable n'est pas déclarée dans la fonction ou déclarée sans var, qui est une variable globale et a une portée globale windowToutes les propriétés de l'objet ont une portée globale. scope; Il est accessible n'importe où dans le code. Les variables déclarées dans une fonction et modifiées avec var sont des variables locales et ne peuvent être utilisées que dans le corps de la fonction. Bien que les paramètres de la fonction n'utilisent pas var, ils le sont. toujours des variables locales.

Il n'y a pas de portée au niveau du bloc

// if语句:

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

var box = "trigkit4";
}
alert(box);//弹出 trigkit4
</script>

La même chose est vraie pour l'instruction de boucle for.

Requête variable

Dans la requête variable, l'accès aux variables locales est plus rapide que les variables globales, il n'est donc pas nécessaire de rechercher la chaîne de portée.

L'exemple suivant :

<script type="text/javascript">
     var name = "Jack";
      function setName(){
           var name = "trigkit4";
           return name;  //从底层向上搜索变量
    }
    alert(setName());      
</script>

Chaque environnement peut rechercher dans la chaîne de portée pour interroger les noms de variables et de fonctions ; mais aucun environnement ne peut être saisi en recherchant dans la chaîne de portée Un autre environnement d'exécution ; Ici, si vous supprimez var name = "trigkit4", alors "Jack" apparaîtra

Problèmes de mémoire

javascript dispose d'un mécanisme automatique de collecte des ordures, une fois que les données ne sont plus utilisées, elles peuvent être défini sur " null" pour libérer la référence

référence circulaire

Un exemple très simple : un objet DOM est référencé par un objet Javascript, et en même temps référence le même ou autre Javascript objet , cet DOM objet peut provoquer des fuites de mémoire. La référence à cet DOM objet ne sera pas collectée par le garbage collector lorsque le script s'arrêtera. Pour rompre la référence circulaire, l'objet faisant référence à l'élément DOM ou la référence à l'objet DOM doit se voir attribuer la valeur null.

Fermeture

Lorsqu'une variable en dehors de la fermeture est introduite dans la fermeture, l'objet ne peut pas être récupéré (GC) à la fin de la fermeture.

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

Fuite DOM

Lorsque le COM d'origine est supprimé, la référence du nœud enfant ne peut pas être recyclée à moins qu'elle ne soit supprimée.

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可以被释放了。

Fuites de minuterie des minuteries

Les minuteries sont également un endroit courant où des fuites de mémoire se produisent :

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)!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn