Maison > Article > interface Web > Premier sujet JavaScript : promotion et précompilation de variables
Table des matières
Tutoriel vidéo Javascript)
Avant-propos
Cet article est la "Série avancée spécialisée JavaScript" 》Le premier article de la série, la série entière comprendra probablement, par exemple :Specialized Advanced car ils ont un "taux d'apparition" élevé à de nombreuses reprises. Afin d'éviter d'être transformés en , la "JavaScript Specialized Advanced Series" est née ! ! ! google内容搜索师
1. Phénomènes intéressants
Selon le bon sens, le code JavaScript doit être exécuté de haut en bas. une chaîne, et bien sûr vous devez déclarer un à l'avance. Si je peux comprendre la vérité profonde, alors je lis le code suivant. 保存string类型的变量
var str = '123';console.log(str); // 123
console.log(str); // undefinedvar str = '123';
Il me semble avoir trouvé un modèle !! !
Après avoir lu les deux premiers morceaux de code et mené une "réflexion approfondie", il me semble avoir trouvé le modèle, c'est-à-dire : dans la fonction après le bloc de code actuel, utiliser des variables dans la variable déclaration et initialisation, Vous n'obtiendrez pas la valeur correcte. 之前
var val = '余光';(function(){ console.log(val); // 余光})();Comme prévu ! , après
déclaration et initialisation des variables Jésus ne peut pas m'empêcher d'obtenir la valeur de val, je l'ai dit ! ! !
Quand j'ai vu le morceau de code suivant, j'étais déjà secoué, quelque chose devait être louche.var val = '余光';(function(){ console.log(val); // undefined var val = '测试';})();Ps : Si vous avez des questions sur l'exécution immédiate de fonctions, vous pouvez aussi bien jeter un œil à "Compréhension approfondie des expressions de fonction JavaScript immédiatement invoquées (IIFE)" ~ Ceci. .. J'ai peur, qu'est-ce que c'est ? Qu'est-ce qui provoque ce phénomène ? Comment Js gère-t-il cela ?
2. Pré-analyse Js
Dans la portée actuelle, peu importe où la variable est déclarée, cela sera fait les coulisses Un mouvement invisible. Remarque :Seules les déclarations sont "déplacées" . Autrement dit, la déclaration et l'affectation sont passivement séparées à un moment donné. Et ce mouvement invisible est en réalité . Js在编译阶段的解析
name = '余光'; // 未添加关键字(未声明),name为全局变量,,即window.name = '余光'var name; // 再次声明name,此时name未进行初始化,它的值是undefined吗?console.log(name); // ?Le résultat est que la "vision périphérique" est imprimée avec succès, de sorte que
mouvement invisible est-ce que cela se produit pendant la pré-analyse Js (compilation).
2.1 Core : Pré-analyseAfin de comprendre ce problème principal, nous devons vérifier que le moteur compilera d'abord le code JavaScript avant de l'interpréter. Une partie de la phase de compilation consiste à rechercher toutes les déclarations et à les associer à la portée appropriée. Les amis intéressés peuvent lire les deux articles "Objets variables en JavaScript" et "De la portée à la chaîne de portée" ~ Par conséquent, lorsque de telles choses se produisent, y compris et 变量
Toutes les déclarations incluses seront traitées avant n'importe quel code est exécuté. Quand vous voyez 函数
;, vous pourriez penser que c'est une déclaration. Mais JavaScript voit en fait cela comme deux déclarations : var a; et a = 2;. var a = 2
// 我们看到的代码:var name = '余光';Mais Js l'analysera en :
// 声明(Declaration)var name; // 声明但未初始化,所以分配 undefined// 初始化(Initialization)name = '余光'; // 初始化(赋值)Donc, un morceau de code dans ce résumé devrait être analysé comme ceci :
var name; // 声明name提到作用域顶部,并被分配了一个undefinedname = '余光'; // 进行初始化操作console.log(name); // '余光'2.2 Remarque : seules les déclarations sont promues
Seules les déclarations seront promues, tandis que les affectations et autres logiques de code ne prendront effet que lorsque le code sera exécuté. Il y aura donc le problème suivant : La fonction
foo();function foo(){ console.log(name); // undefined var name = '余光';}est promue et peut naturellement être exécutée normalement, mais la variable est uniquement déclarée promue. 2.3 Chaque scope sera promu Toujours le code ci-dessus :
foo();function foo(){ console.log(name); // undefined var name = '余光';}En fait, il ressemble à ceci au moment de la compilation :
function foo(){ var name; // 声明 console.log(name); // undefined name = '余光'; // 初始化}foo(); // 函数执行
3. Priorité entre les promotions
Maintenant que nous savons que et 变量
seront promus, comment juger entre elles. Et la priorité ? 函数
我们分析下面的代码:
foo();var foo; // 1function foo(){ console.log('余光');}foo = function(){ console.log('小李');}
本着函数优先提升的原则,他会被解析成这样:
function foo(){ console.log('余光');}foo(); // 余光foo = function(){ console.log('小李');}
注意,var foo
因为是一个重复声明,且优先级低于函数声明
所以它被忽略掉了。
最直观的例子,就是在函数字面量前调用该函数:
foo();var foo = function(){ console.log(1);}// TypeError: foo is not a function
这段程序中:
foo
被提升并分配给所在作用域(在这里是全局作用域),因此在执行foo()时不会导致ReferenceError(),而是会提示你 foo is not a function
。四、ES6和小结
ES6新增了两个命令let
和const
,用来声明变量,有关它们完整的概念我会在《ES6基础系列》中总结,提起它们,是因为变量提升在它们身上不会存在。
let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
// var 的情况console.log(foo); // 输出undefinedvar foo = 2;// let 的情况console.log(bar); // 报错ReferenceErrorlet bar = 2;
上面代码中,变量foo用var命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。变量bar用let命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。
在变量提升上,const和let一样,只在声明所在的块级作用域内有效,也不会变量提升
最后提炼一下:JavaScript引擎并不总是按照代码的顺序来进行解析。在编译阶段,无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理,这个过程被称为提升。声明本身会被提升,而包括函数表达式的赋值在内的赋值操作并不会提升。
相关免费学习推荐:javascript(视频)
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!