Maison > interface Web > js tutoriel > Analyse détaillée de let et const dans la liaison au niveau du bloc es6

Analyse détaillée de let et const dans la liaison au niveau du bloc es6

不言
Libérer: 2019-03-30 09:43:18
avant
2608 Les gens l'ont consulté

Cet article vous apporte une analyse détaillée de let et const dans la liaison au niveau du bloc es6. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

La déclaration de variable a toujours été la partie la plus subtile du travail en js. Contrairement au langage C, les variables sont toujours déclarées lors de leur création. Le langage js vous permet de déclarer des variables lorsque vous en avez besoin.

var let const déclaration de variable

var déclaration et promotion de variable.

Lorsque nous utilisons le mot-clé var pour déclarer une variable, peu importe où la variable est déclarée, elle sera déclarée en haut de la fonction où elle se trouve (si elle n'est pas dans la fonction, elle sera être considéré comme global) Le sommet du domaine) C'est ce qu'on appelle le levage de variable

var est hissé comme suit :

function getValue(condition) {
if (condition) {
var value = "blue";
// 其他代码
return value;
} else {
// value 在此处可访问,值为 undefined
return null;
}
// value 在此处可访问,值为 undefined
}
Copier après la connexion

Déclaration au niveau du bloc let

Bloquer. La déclaration -level consiste à laisser la déclaration Les variables ne sont pas accessibles en dehors de la portée spécifiée. Les portées au niveau du bloc sont créées dans les situations suivantes :

  1. à l'intérieur d'une fonction,
  2. dans un code. block (constitué d'une paire entourée d'accolades)

La syntaxe de la déclaration let est cohérente avec la déclaration var Puisque la déclaration let ne promouvra pas la variable en haut de la fonction, nous devons le faire manuellement. placez la déclaration let en haut afin que la variable puisse être placée en haut de la fonction. L'intégralité du bloc de code est disponible à l'intérieur.

Comme indiqué ci-dessous :

function getValue(condition) {
if (condition) {
let value = "blue";
// 其他代码
return value;
} else {
// value 在此处不可用
return null;
}
// value 在此处不可用
}
Copier après la connexion

La duplication des identifiants est interdite

Si un identifiant a été défini dans le code, des instructions let répétées signaleront une erreur

var a = 30;
//报错
let a = 30;
Copier après la connexion

Une variable est déclarée deux fois : une fois en utilisant var et une autre fois en utilisant let. Parce que let ne peut pas re-déclarer un identifiant existant dans la même portée, la déclaration let ici générera une erreur. D'un autre côté, utiliser let pour déclarer une nouvelle variable avec le même nom dans une portée imbriquée ne générera pas d'erreur. Le code suivant le démontre :

var count = 30;
// 不会抛出错误
if (condition) {
let count = 40;
// 其他代码
}
Copier après la connexion

Aucune erreur ne sera générée dans ce code. Faux, le point clé est que si let est déclaré à plusieurs reprises dans le même bloc de code de niveau, une erreur sera signalée

déclaration de constante const

peut être déclarée en utilisant const syntaxe dans es6. Les variables déclarées à l'aide de const sont considérées comme des constantes, ce qui signifie que leurs valeurs ne peuvent pas être modifiées après avoir été définies. Pour cette raison, toutes les variables const doivent être initialisées lorsqu'elles sont déclarées. La variable

// 有效的常量
const maxItems = 30;
// 语法错误:未进行初始化
const name;
Copier après la connexion

maxItems est initialisée, afin que sa déclaration const puisse fonctionner normalement. La variable name n'a pas été initialisée, ce qui a provoqué une erreur lors de la tentative d'exécution de ce code. La déclaration const empêchera la liaison de variables et la modification des valeurs auto-générées, ce qui signifie que la déclaration const n'empêchera pas la modification des membres de variables. Par exemple :

const person = {
name: "Nicholas"
};
// 工作正常
person.name = "Greg";
// 抛出错误
person = {
name: "Greg"
};
Copier après la connexion

Comparaison de la déclaration const et de la déclaration let

  1. Tout d'abord, ce sont des déclarations au niveau du bloc, ce qui signifie que les constantes sont en dehors de l'instruction Le bloc dans lequel ils sont déclarés n'est pas accessible et la déclaration ne sera pas promue. Les exemples sont les suivants :

if (condition) {
const maxItems = 5;
// 其他代码
}
// maxItems 在此处无法访问
Copier après la connexion
  1. Lorsqu'ils sont déclarés à plusieurs reprises. dans la portée unifiée, ils provoqueront une erreur

Zone morte temporaire

Lorsque nous utilisons let ou const pour déclarer, elle est inaccessible avant d'atteindre la déclaration If. nous essayons Access entraînera une erreur de référence. Ce problème se pose en raison de la zone morte temporaire

Lorsque le moteur JS examine le prochain bloc de code et trouve une déclaration de variable, il promouvra la déclaration en fonction ou en portée globale face à var top, en faisant face à let ou const placera la déclaration dans une zone morte temporaire. Toute tentative d'accès à une variable dans la zone morte temporaire entraînera une erreur « d'exécution ». Ce n'est que lorsque l'instruction de déclaration de la variable est exécutée que la variable sera supprimée de la zone morte temporaire et pourra être utilisée en toute sécurité.

Liaison au niveau du bloc dans la boucle

for (var i = 0; i < 10; i++) {
process(items[i]);
}
// i 在此处仍然可被访问
console.log(i); // 10
Copier après la connexion

Le résultat de sortie n'est pas la valeur attendue mais 10 c'est à cause de la promotion de la variable provoquée par la déclaration var. Si vous êtes intelligent, vous penserez certainement à utiliser la liaison au niveau du bloc pour déclarer les variables.

for (let i = 0; i < 10; i++) {
process(items[i]);
}

console.log(i);
Copier après la connexion

i sera-t-il affiché normalement ici ? En fait, ce ne sera pas le cas dans cet exemple ? rapporté Pourquoi ? Parce que je ne suis pas accessible ici. La variable i dans cet exemple n'est disponible que dans la boucle for et n'est accessible nulle part une fois la boucle terminée.

Jetons un coup d'œil au code

var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push(function() { console.log(i); });
}
funcs.forEach(function(func) {
func(); // 输出数值 "10" 十次
});
Copier après la connexion

Vous auriez pu vous attendre à ce que ce code imprime une valeur de 0 à 9, mais à la place, il imprime la valeur 10 dix fois sur le même ligne. En effet, la variable i est partagée à chaque itération de la boucle, ce qui signifie que les fonctions créées dans la boucle ont toutes une référence à la même variable. Une fois la boucle terminée, la valeur de la variable i sera 10 , donc lorsque console.log(i) est appelé,
affiche 10 à chaque fois.

Pour résoudre ce problème, les développeurs utilisent des expressions de fonction immédiatement invoquées (IIFE) dans les boucles pour forcer la création d'une nouvelle copie de la variable à chaque itération, comme indiqué ci-dessous :

var funcs = [];
for (var i = 0; i < 10; i++) {
funcs.push((function(value) {
return function() {
console.log(value);
}
}(i)));
}
funcs.forEach(function(func) {
func(); // 从 0 到 9 依次输出
});
Copier après la connexion

instruction let à l'intérieur d'une boucle

L'instruction let simplifie la boucle en imitant efficacement l'effet de l'IIFE dans l'exemple ci-dessus. A chaque itération, une nouvelle variable
du même nom est créée et initialisée. Cela signifie que vous pouvez omettre complètement IIFE et obtenir le résultat souhaité, comme celui-ci

var funcs = [];
for (let i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}
funcs.forEach(function(func) {
func(); // 从 0 到 9 依次输出
})
Copier après la connexion

我们是否会想到这个问题:为什么同样的代码使用let声明会导致不一样的结果呢?
在循环中let声明每次都创建了一个新的i变量,因此在循环内部创建的函数获得了各自的i副本,而每个i副本的值都会在每次的循环迭代声明变量的时候确定了

var funcs = [],
object = {
a: true,
b: true,
c: true
};
for (let key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次输出 "a"、 "b"、 "c"
});
Copier après la connexion

本例中的 for-in 循环体现出了与 for 循环相同的行为。每次循环,一个新的 key 变量绑定就被创建,因此每个函数都能够拥有它自身的 key 变量副本,结果每个函数都输出了一个不同的值。而如果使用 var 来声明 key ,则所有函数都只会输出 "c" 。
let 声明在循环内部的行为是在规范中特别定义的,而与不提升变量声明的特征没有必然联系。事实上,在早期 let 的实现中并没有这种行为,它是后来才添加的。

循环内的常量声明

虽然es6没有明确的规范我们不能在for循环中使用const声明,然而它会根据循环方式的不同而有不同的行为,我们可以在初始化时使用const,但是当循环试图改变变量的值的时候会抛出错误,例如:

var funcs = [];
// 在一次迭代后抛出错误
for (const i = 0; i < 10; i++) {
funcs.push(function() {
console.log(i);
});
}
Copier après la connexion

在此代码中, i 被声明为一个常量。循环的第一次迭代成功执行,此时 i 的值为 0 。在
i++ 执行时,一个错误会被抛出,因为该语句试图更改常量的值。因此,在循环中你只能使
用 const 来声明一个不会被更改的变量
而另一方面, const 变量在 for-in 或 for-of 循环中使用时,与 let 变量效果相同。因
此下面代码不会导致出错:

var funcs = [],
object = {
a: true,
b: true,
c: true
};
// 不会导致错误
for (const key in object) {
funcs.push(function() {
console.log(key);
});
}
funcs.forEach(function(func) {
func(); // 依次输出 "a"、 "b"、 "c"
});
Copier après la connexion

这段代码与“循环内的 let 声明”小节的第二个例子几乎完全一样,唯一的区别是 key 的值在
循环内不能被更改。 const 能够在 for-in 与 for-of 循环内工作,是因为循环为每次迭
代创建了一个新的变量绑定,而不是试图去修改已绑定的变量的值(就像使用了 for 而不是
for-in 的上个例子那样)。

全局块级绑定

let 与 const 不同于 var 的另一个方面是在全局作用域上的表现。当在全局作用域上使用 var 时,它会创建一个新的全局变量,并成为全局对象(在浏览器中是 window )的一
个属性。

总结

let和const块级作用域的引入,能够使我们减少很多无心的错误,它们的一个副作用,是不能在变量声明位置之前访问它们

块级绑定当前的最佳实践就是:在默认情况下使用 const ,而只在你知道变量值需要被更改的情况下才使用 let 。这在代码中能确保基本层次的不可变性,有助于防止某些类型的错误。

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的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!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal