Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Analyse von let und const in der ES6-Bindung auf Blockebene

Detaillierte Analyse von let und const in der ES6-Bindung auf Blockebene

不言
不言nach vorne
2019-03-30 09:43:182510Durchsuche

Dieser Artikel bietet Ihnen eine detaillierte Analyse von let und const in der es6-Block-Level-Bindung. Ich hoffe, dass er Ihnen als Referenz dienen wird.

Variablendeklaration war schon immer der subtilste Teil der JS-Arbeit. Im Gegensatz zur C-Sprache können Sie Variablen immer dann deklarieren, wenn Sie sie erstellen.

var let const Variablendeklaration

var Deklaration und Variablenförderung.

Wenn wir das Schlüsselwort var verwenden, um eine Variable zu deklarieren, wird sie unabhängig davon, wo sie deklariert wird, oben in der Funktion deklariert, wo sie sich befindet (wenn sie sich nicht innerhalb der Funktion befindet, wird sie deklariert). als global angesehen werden) Die Spitze der Domäne) Dies wird als Variablen-Heben (Heben) bezeichnet.

Var wird wie folgt gehisst:

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

Deklaration auf Blockebene let

Block -Level-Deklaration soll zulassen, dass auf die deklarierte Variable nicht außerhalb des angegebenen Bereichs zugegriffen werden kann. Bereiche auf Blockebene werden erstellt, wenn sich

  1. innerhalb einer Funktion und
  2. innerhalb eines Codeblocks befindet (getrennt durch ein Paar geschweifte Klammern) im Inneren

Die Syntax der let-Deklaration stimmt mit der var-Deklaration überein, da die Variable durch die let-Deklaration nicht an die Spitze der Funktion befördert wird um die let-Deklaration manuell an den Anfang zu setzen, damit die Variable an den Anfang des gesamten Codes gesetzt werden kann. Verfügbar innerhalb des Blocks.

Wie unten gezeigt:

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

Duplizierung von Bezeichnern ist verboten

Wenn ein Bezeichner im Code definiert wurde, melden wiederholte let-Anweisungen einen Fehler

var a = 30;
//报错
let a = 30;

Die a-Variable wird zweimal deklariert: einmal mit var und ein anderes Mal mit let. Da let einen vorhandenen Bezeichner im selben Bereich nicht erneut deklarieren kann, löst die let-Deklaration hier einen Fehler aus. Andererseits wird die Verwendung von „let“ zum Deklarieren einer neuen Variablen mit demselben Namen in einem verschachtelten Bereich keinen Fehler auslösen. Der folgende Code zeigt dies:

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

In diesem Code wird kein Fehler ausgegeben Der Punkt ist, dass, wenn let wiederholt im Codeblock derselben Ebene deklariert wird, ein Fehler gemeldet wird.

const-Konstantendeklaration

kann mit der const-Syntax in es6 deklariert werden. Mit const deklarierte Variablen gelten als Konstanten, was bedeutet, dass ihre Werte nach dem Festlegen nicht mehr geändert werden können. Aus diesem Grund müssen alle const-Variablen bei der Deklaration initialisiert werden. Die Variable

// 有效的常量
const maxItems = 30;
// 语法错误:未进行初始化
const name;

maxItems wird initialisiert, damit ihre const-Deklaration normal funktionieren kann. Die Namensvariable wurde nicht initialisiert, was dazu führte, dass beim Versuch, diesen Code auszuführen, ein Fehler ausgegeben wurde. Die const-Deklaration verhindert die Variablenbindung und die Änderung selbst generierter Werte, was bedeutet, dass die const-Deklaration die Änderung von Variablenmitgliedern nicht verhindert. Zum Beispiel:

const person = {
name: "Nicholas"
};
// 工作正常
person.name = "Greg";
// 抛出错误
person = {
name: "Greg"
};

Vergleich von const-Deklaration und let-Deklaration

  1. Erstens handelt es sich um Deklarationen auf Blockebene, was bedeutet, dass Konstanten nicht außerhalb des Anweisungsblocks liegen dürfen in der auf sie zugegriffen wird, und die Deklaration wird nicht hochgestuft:

if (condition) {
const maxItems = 5;
// 其他代码
}
// maxItems 在此处无法访问
  1. Sie führen dazu, dass ein Fehler ausgelöst wird Sie werden wiederholt im einheitlichen Bereich deklariert

Temporäre Totzone

Wenn wir let oder const zum Deklarieren verwenden, können wir erst dann darauf zugreifen, wenn wir den Deklarationspunkt erreichen Wenn wir versuchen, darauf zuzugreifen, führt dies zu einem Zitierfehler. Dieses Problem entsteht aufgrund der temporären Totzone

Wenn die JS-Engine den nächsten Codeblock betrachtet und eine Variablendeklaration findet, wird sie die Deklaration angesichts von var top in die Funktion oder den globalen Bereich hochstufen. Wenn Sie mit let oder const konfrontiert sind, wird die Deklaration vorübergehend in eine tote Zone versetzt. Jeder Versuch, auf eine Variable innerhalb der temporären Totzone zuzugreifen, führt zu einem „Laufzeit“-Fehler. Erst wenn die Deklarationsanweisung der Variablen ausgeführt wird, wird die Variable aus der temporären Totzone entfernt und kann sicher verwendet werden.

Bindung auf Blockebene in der Schleife

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

Das Ausgabeergebnis ist nicht der erwartete Wert, sondern 10, weil die Variable durch die var-Deklaration hochgestuft wird. Wenn Sie schlau sind, werden Sie auf jeden Fall darüber nachdenken, Variablen auf Blockebene zu deklarieren.

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

console.log(i);

i Wird es hier tatsächlich keinen Fehler verursachen? . Warum? Weil ich hier nicht erreichbar bin. Die Variable i in diesem Beispiel ist nur innerhalb der for-Schleife verfügbar und kann nach Ende der Schleife nirgendwo mehr aufgerufen werden.

Schauen wir uns den Code an

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

Vielleicht haben Sie erwartet, dass dieser Code einen Wert von 0 bis 9 ausgibt, aber stattdessen gibt er den Wert 10 zehnmal in derselben Zeile aus. Dies liegt daran, dass die Variable i in jeder Iteration der Schleife gemeinsam genutzt wird, was bedeutet, dass die innerhalb der Schleife erstellten Funktionen alle einen Verweis auf dieselbe Variable haben. Nach dem Ende der Schleife beträgt der Wert der Variablen i 10. Wenn also console.log(i) aufgerufen wird, gibt
jedes Mal 10 aus.

Um dieses Problem zu beheben, verwenden Entwickler Instant Invoked Function Expressions (IIFEs) innerhalb von Schleifen, um die Erstellung einer neuen Kopie der Variablen bei jeder Iteration zu erzwingen, wie unten gezeigt:

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 依次输出
});

let-Deklaration innerhalb einer Schleife

Die let-Deklaration vereinfacht die Schleife, indem sie den Effekt des IIFE im obigen Beispiel effektiv nachahmt. Bei jeder Iteration wird eine neue
-Variable mit demselben Namen erstellt und initialisiert. Das bedeutet, dass Sie IIFE vollständig weglassen können und das gewünschte Ergebnis erhalten, wie folgt

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

我们是否会想到这个问题:为什么同样的代码使用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"
});

本例中的 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);
});
}

在此代码中, 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"
});

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

全局块级绑定

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

总结

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

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

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!

Das obige ist der detaillierte Inhalt vonDetaillierte Analyse von let und const in der ES6-Bindung auf Blockebene. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen