Maison  >  Article  >  interface Web  >  Qu'est-ce que la préinterprétation JavaScript ? Analyse de pré-interprétation JavaScript (avec code)

Qu'est-ce que la préinterprétation JavaScript ? Analyse de pré-interprétation JavaScript (avec code)

不言
不言avant
2018-11-16 14:58:231785parcourir

Le contenu de cet article porte sur qu'est-ce que la pré-interprétation JavaScript ? L'analyse de la pré-interprétation JavaScript (avec code) a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer, j'espère qu'elle vous sera utile.

JavaScript est un langage interprété. L'exécution de code JavaScript nécessite deux étapes

  • Étape de compilation : L'étape de compilation est ce que nous appelons souvent l'étape de pré-interprétation (prétraitement) JavaScript, à ce stade l'interpréteur JavaScript terminera la conversion du code du script JavaScript en bytecode

  • Étape d'exécution : Lors de l'étape de compilation, l'interpréteur JavaScript convertit le bytecode en bytecode à l'aide de l'exécution environnement Générez du code mécanique et exécutez-le séquentiellement de haut en bas

Cet article se concentre sur la pré-interprétation. Le schéma du cadre est le suivant :

Quest-ce que la préinterprétation JavaScript ? Analyse de pré-interprétation JavaScript (avec code)

1. Qu'est-ce que la pré-interprétation

Pré-interprétation :

Avant l'exécution du code JavaScript, le navigateur déclarera ou définira d'abord tout avec var et fonctionnera à l'avance par défaut

1. Comprendre les déclarations et les définitions

Déclarer : Par exemple, var num;=> indique au navigateur qu'il existe une variable num dans la portée globale ; déclaré mais Il n'y a pas d'affectation et la valeur par défaut est indéfinie

Définition (définie) : Par exemple, num=12;=> attribue une valeur à notre variable.

2. Pour ceux qui ont des mots-clés var et function, les opérations sont différentes lors de la pré-interprétation

var => n'est déclaré à l'avance que lors de la pré-interprétation

function = > Lors de la pré-interprétation, toutes les premières déclarations et définitions sont complétées

3. La pré-interprétation n'a lieu que dans le périmètre actuel.

Par exemple : Au début, seul le contenu sous la fenêtre sera pré-interprété, et le contenu de la fonction ne sera pré-interprété que lorsque la fonction sera exécutée

2. Chaîne de portée

1 .Comment faire la distinction entre les variables privées et les variables globales ?

1) Les variables déclarées dans la portée globale (lorsqu'elles sont pré-interprétées) sont des variables globales

2) Seule l'exécution de la fonction produira des domaines d'effets privés, tels quant à(){}, if(){} et switch(){} ne généreront pas de portée privée

3) Variables déclarées dans "portée privée" (déclaration var)" et Les "paramètres de fonction" sont tous deux des variables privées . Dans le domaine privé, lorsque le code est exécuté et qu'une variable est rencontrée, nous devons d'abord déterminer s'il s'agit d'une variable privée. Si c'est une variable privée, elle n'a aucune relation avec l'extérieur. ira à Rechercher la portée de niveau supérieur de la portée actuelle. S'il n'y a pas de portée de niveau supérieur, continuez la recherche jusqu'à ce que la fenêtre soit trouvée. Il s'agit de la chaîne de portée.

Prenons un exemple pour distinguer les variables privées des variables globales :

//=>变量提升:var a;var b;var c;test=AAAFFF111;
var a=10,b=11,c=12;
function test(a){
//=>私有作用域:a=10 var b;
a=1;//=>私有变量a=1
var b=2;//=>私有变量b=2
c=3;//=>全局变量c=3
}
test(10);
console.log(a);//10
console.log(b);//11
console.log(c);//3

Un critère pour juger s'il s'agit d'une variable privée est de savoir s'il s'agit d'une variable déclarée dans var dans une fonction. Les paramètres formels sont tous des variables privées . Dans cette question, dans la fonction test, a est un paramètre formel et la variable b définie par var b est une variable privée.

2. Passage des paramètres de fonction

En effet, lorsque la fonction est exécutée, une nouvelle portée privée sera d'abord formée, puis exécutée selon les étapes suivantes :

1) S'il y a des paramètres formels, attribuez d'abord des valeurs aux paramètres formels

2) Effectuer une pré-interprétation dans la portée privée

3) Le code dans la portée privée est exécuté de haut en bas

Regardons un exemple de question

var total=0;
function fn(num1,num2){
console.log(total);//->undefined 外面修改不了私有的
var total=num1 +num2;
console.log(total);//->300
}
fn(100,200);
console.log(total);//->0 私有的也修改不了外面的
Classification de la mémoire en JS

Mémoire de pile : utilisée pour fournir un environnement pour l'exécution du code JS, c'est-à-dire la portée (portée globale/portée privée)

Mémoire tas : utilisée pour stocker les valeurs des types de données de référence. Les objets stockent les noms et les valeurs d'attribut, et les fonctions stockent les chaînes de code.


3. La différence entre la portée globale avec var et sans var

Regardons d'abord les deux exemples suivants :

//例题1
console.log(num);//->undefined
var num=12;
Quand vous regardez Quand var num=12, vous pensez peut-être que ce n'est qu'une déclaration. Mais
//例题2
console.log(num2);//->Uncaught ReferenceError:num2 is not defined 
num2=12;//不能预解释
JavaScript le traitera en fait comme deux déclarations : var num; et num=12; La première déclaration de définition est faite lors de la phase de pré-interprétation. La deuxième instruction d'affectation sera laissée en place en attendant la phase d'exécution

. num2=12 équivaut à ajouter un nom d'attribut appelé num2 à la fenêtre, et la valeur de l'attribut est 12 ; et var num=12 équivaut à ajouter une variable globale num à la portée globale. à la fenêtre. Le nom de l'attribut est num2 et la valeur de l'attribut est 12. La plus grande différence entre les deux : celui avec var peut être pré-interprété, donc aucune erreur ne sera signalée lors de son exécution avant l'affectation ; celui sans var ne peut pas être pré-interprété, et une erreur sera signalée lors de son exécution ; before; Ensuite, donnons un exemple :

//例题1
var total=0;
function fn(){
console.log(total);//undefined
var total=100;
}
fn();
console.log(total);//0
Dans l'exemple 1, la variable var peut être pré-interprétée dans la portée privée, donc la valeur imprimé par la première console n'est pas défini.
//例题2
var total=0;
function fn(){
console.log(total);//0
total=100;
}
fn();
console.log(total);//100
Si une variable qui apparaît dans la portée privée n'est pas privée, recherchez dans la portée de niveau supérieur, continuez la recherche vers le haut jusqu'à ce que vous trouviez la fenêtre

. , la variable sans var n'est pas privée, alors allez voir vos supérieurs 4. Pré-expliquez les cinq principaux comportements contraires à l'éthique

1. Lors de la pré-explication, peu importe si vos conditions sont établies ou pas, vous devez déclarer le var à l'avance.

Veuillez regarder l'exemple de question suivant :

if(!("num" in  window)){
var num=12;//这句话会被提到大括号之外的全局作用域:var num;->window.num; 
}
console.log(num);//undefined

2.预解释的时候只预解释”=”左边的,右边的值,不参与预解释

请看下面这道例题:

fn();//报错
var fn=function (){  //window下的预解释:var fn;
console.log("ok");
};

3.自执行函数:定义和执行一起完成了。

自执行函数定义的那个function在全局作用域下不进行预解释,当代码执行到这个位置的时候定义和执行一起完成了。常见有以下几种形式:

(function(num){})(10);
~function(num){}(10);
+function(num){}(10);
-function(num){}(10);
!function(num){}(10);

4.函数体中return下面的代码虽然不再执行了,但是需要进行预解释;return后面跟着的都是我们返回的值,所以不进行预解释;

function fn(){
//预解释:var num;
console.log(num);//->undefined
return function(){};
var num=100;
}

5.函数声明和变量声明都会被提升。但是一个值得注意的细节(这个细节可以出现在有多个“重复”声明的代码中)是函数会首先被提升,然后才是变量。在预解释的时候,如果名字已经声明过了,不需要从新的声明,但是需要重新的赋值;

我们先来看下两个简单的例子:

//例题1
 function a() {}
  var a
  console.log(typeof a)//'function'
//例题2
  var c = 1
  function c(c) {
    console.log(c)
    var c = 3
  }
  c(2)//Uncaught TypeError: c is not a function

当遇到存在函数声明和变量声明都会被提升的情况,函数声明优先级比较高,最后变量声明会被函数声明所覆盖,但是可以重新赋值,所以上个例子可以等价为

 function c(c) {
  console.log(c)
    var c = 3
  }
 c = 1
 c(2)

接下来我们看下两道比较复杂的题目:

//例题3
fn();
function fn(){console.log(1);};
fn();
var fn=10;
fn();
function fn(){console.log(2);};
fn();

1.一开始预解释,函数声明和赋值一起来,fn 就是function fn(){console.log(1);};遇到var fn=10;不会重新再声明,但是遇到function fn(){console.log(2);}就会从重新赋值,所以一开始fn()的值就是2

2.再执行fn();值不变还是2

3.fn重新赋值为10,所以运行fn()时报错,接下去的语句就没再执行。

//例题4
alert(a);
a();
var a=3;
function a(){
alert(10)
}
alert(a);
a=6;
a()

1.函数声明优先于变量声明,预解释时候,函数声明和赋值一起来,a就是function a(){alert(10)} ,后面遇到var a=3,也无需再重复声明,所以先弹出function a(){alert(10)}

2.a(),执行函数,然后弹出10

3.接着执行了var a=3; 所以alert(a)就是显示3

4.由于a不是一个函数了,所以往下在执行到a()的时候, 报错。


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer