Heim > Web-Frontend > Front-End-Fragen und Antworten > Zählt die in es6 eingeschlossene Variable als innerhalb des Blocks?

Zählt die in es6 eingeschlossene Variable als innerhalb des Blocks?

青灯夜游
Freigeben: 2022-11-21 16:21:58
Original
1443 Leute haben es durchsucht

es6 Innerhalb des von if umschlossenen Variablenberechnungsblocks. In es6 gibt es einen neuen Bereich auf Blockebene. Der von „{}“ umschlossene Code ist der Bereich auf Blockebene, die if-Anweisung und der Code in der for-Schleife in der Funktion. Ebenenumfang und werden innerhalb des Blocks berechnet. In es6 dürfen Bereiche auf Blockebene beliebig verschachtelt werden. Der äußere Bereich kann keine Variablen des inneren Bereichs lesen.

Zählt die in es6 eingeschlossene Variable als innerhalb des Blocks?

Die Betriebsumgebung dieses Tutorials: Windows 7-System, ECMAScript Version 6, Dell G3-Computer.

Was ist der Bereich auf Blockebene?

Der Bereich auf Blockebene ist neu in ES6. Der Blockbereich wird durch { umschlossen. Der { in der if-Anweisung und die for-Anweisung gehören ebenfalls dazu zum Blockbereich. ES6 中新增了块级作用域。块作用域由 { } 包裹,if 语句和 for 语句里面的 { } 也属于块作用域。

函数中的{},if语句,for循环,也是属于块级作用域,let与const定义的变量只能在作用域有效。

为什么需要块级作用域

第一种场景:内部变量会覆盖外部变量

var time = new Date()
function fx () {
    console.log(time) // undefined
    if (false) {
        var time = 'hello'
    }
}
fx()
Nach dem Login kopieren
{
    var a = 1
    console.log(a) // 1
}
console.log(a) // 1
// 通过var定义的变量可以跨块作用域访问到。
Nach dem Login kopieren

第二种场景:用来计数的循环变量泄漏为全局变量

for 循环中的用 var 定义的变量在外部作用域可以访问

for (var i = 0; i < 3; i++) {

}

for (let j = 0; j < 3; j++) {

}
// 3
console.log(i);
// Uncaught ReferenceError: j is not defined
console.log(j);
Nach dem Login kopieren

if 语句中 var 定义的变量在外部作用域可以访问

if(true)if (false) 的区别

  • if(true) 中的赋值语句会被执行,所以 a 打印出来是 3
  • if(false) 中的赋值语句不会被执行,但声明的变量 var b 会由于变量提升,提升到作用域的顶层,所以打印出来是 undefined
if (true) {
	var a = 3
}

if (false) {
	var b = 3
}
// 3
console.log(a);
// undefined
console.log(b);

if (true) {
	let c = 3
}
// Uncaught ReferenceError: c is not defined
console.log(c);
Nach dem Login kopieren

块级作用域(ES6 提供 let & const 变量实现块级作用域)

function fxFn () { // 这是一个块级作用域
    let fx = 'fx is a great girl'
    if (true) { // 这是一个块级作用域
        let fx = 'fx is 18 years old'
    }
    console.log(fx) // fx is a great girl
}
fxFn()
 
// 块级作用域之间相互不影响
Nach dem Login kopieren

ES6 允许块级作用域的任意嵌套。

{{{{
  {
    let fnn = 'Hello'
  }
  console.log(fnn); // 报错
}}}};
Nach dem Login kopieren

上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。

  • 内层作用域可以定义外层作用域的同名变量。
{{{{
  let fnn = 'Hello';
  {
    let fnn = 'Hello'
  }
}}}};
Nach dem Login kopieren

块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE)不再必要了。

// IIFE 写法
(function () {
  var tmp = '...';
  // ...
}());
 
// 块级作用域写法
{
  let tmp = '...';
  // ...
}
Nach dem Login kopieren

块级作用域与函数声明

ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。

// 情况一
if (true) {
  function f() {}
}
 
// 情况二
try {
  function f() {}
} catch(e) {
  // ...
}
Nach dem Login kopieren

上面两种函数声明,根据 ES5 的规定都是非法的。

但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。

ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于 let,在块级作用域之外不可引用。

function f() { console.log('I am outside!'); }
 
(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }
 
  f();
}());
Nach dem Login kopieren

上面代码在 ES5 中运行,会得到“I am inside!”,因为在 if 内声明的函数 f 会被提升到函数头部,实际运行的代码如下。

// ES5 环境
function f() { console.log('I am outside!'); }
 
(function () {
  function f() { console.log('I am inside!'); }
  if (false) {
  }
  f();
}());
Nach dem Login kopieren

ES6 就完全不一样了,理论上会得到“I am outside!”。因为块级作用域内声明的函数类似于 let,对作用域之外没有影响。
但是,如果你真的在 ES6 浏览器中运行一下上面的代码,是会报错的,这是为什么呢?

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
 
(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }
 
  f();
}());
// Uncaught TypeError: f is not a function
Nach dem Login kopieren

上面的代码在 ES6 浏览器中,都会报错。

原来,如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式

  • 允许在块级作用域内声明函数。
  • 函数声明类似于 var,即会提升到全局作用域或函数作用域的头部。
  • 同时,函数声明还会提升到所在的块级作用域的头部。

注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作 let 处理。

根据这三条规则,浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于 var

{}, if-Anweisungen und for-Schleifen in Funktionen gehören ebenfalls zum Gültigkeitsbereich auf Blockebene. Variablen, die durch let und const definiert werden, können nur im Gültigkeitsbereich gültig sein.

🎜🎜Warum ein Bereich auf Blockebene benötigt wird🎜🎜🎜Erstes Szenario: Interne Variablen überschreiben externe Variablen🎜
// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
(function () {
  var f = undefined;
  if (false) {
    function f() { console.log('I am inside!'); }
  }
 
  f();
}());
// Uncaught TypeError: f is not a function
Nach dem Login kopieren
// 块级作用域内部的函数声明语句,建议不要使用
{
  let a = 'secret';
  function f() {
    return a;
  }
}
 
// 块级作用域内部,优先使用函数表达式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}
Nach dem Login kopieren
Nach dem Login kopieren
🎜Zweites Szenario: Die Schleifenvariable, die zum Zählen von Lecks als globale Variable verwendet wird 🎜🎜 Auf Variablen, die mit var in der for-Schleife definiert wurden, kann im externen Bereich🎜
// 第一种写法,报错
if (true) let x = 1;
 
// 第二种写法,不报错
if (true) {
  let x = 1;
}
Nach dem Login kopieren
Nach dem Login kopieren
🎜 var in den Variablen der <code>if-Anweisung zugegriffen werden Definiert durch Code> kann im externen Bereich zugegriffen werden🎜🎜🎜Der Unterschied zwischen if(true) und if (false)🎜🎜
  • Die Zuweisungsanweisung in if(true) wird ausgeführt, sodass a als 3
  • if(false) ausgegeben wird ) Die Zuweisungsanweisung in wird nicht ausgeführt, aber die deklarierte Variable var b wird aufgrund der Variablenheraufstufung auf die oberste Ebene des Bereichs heraufgestuft, sodass sie als gedruckt wird undefiniert
// 不报错
'use strict';
if (true) {
  function f() {}
}
 
// 报错
'use strict';
if (true)
  function f() {}
Nach dem Login kopieren
Nach dem Login kopieren
🎜
🎜🎜Bereich auf Blockebene (ES6 stellt let- und const-Variablen zur Implementierung des Bereichs auf Blockebene bereit)🎜🎜rrreee🎜ES6 ermöglicht beliebige Einbettung des Bereichssatzes auf Blockebene. 🎜rrreee🎜Der obige Code verwendet einen Blockebenenbereich mit fünf Ebenen, und jede Ebene ist ein separater Bereich. Der Bereich der vierten Ebene kann die internen Variablen des Bereichs der fünften Ebene nicht lesen. 🎜
  • Der innere Bereich kann Variablen mit demselben Namen wie der äußere Bereich definieren.
rrreee🎜Das Aufkommen des Bereichs auf Blockebene macht den weit verbreiteten anonymen, sofort ausgeführten Funktionsausdruck (anonymous IIFE) tatsächlich nicht mehr notwendig. 🎜rrreee🎜
🎜🎜Bereichs- und Funktionsdeklaration auf Blockebene🎜🎜🎜ES5 legt fest, dass Funktionen nur im Bereich und Funktionsbereich der obersten Ebene deklariert werden können, nicht im Block Bereichsdeklaration auf -Ebene. 🎜rrreee🎜Die beiden oben genannten Funktionsdeklarationen sind gemäß ES5 illegal. 🎜🎜Um jedoch mit altem Code kompatibel zu sein, unterstützen Browser weiterhin die Deklaration von Funktionen in Bereichen auf Blockebene. Daher können die beiden oben genannten Situationen tatsächlich ausgeführt werden, ohne dass Fehler gemeldet werden. 🎜🎜ES6 führte den Bereich auf Blockebene ein und ermöglichte explizit die Deklaration von Funktionen im Bereich auf Blockebene. ES6 legt fest, dass sich Funktionsdeklarationsanweisungen im Bereich auf Blockebene wie let verhalten und nicht außerhalb des Bereichs auf Blockebene referenziert werden können. 🎜rrreee🎜Wenn der obige Code in ES5 ausgeführt wird, erhalten Sie „Ich bin drinnen!“, da die Funktion innerhalb von <code>ifdeklariert wurde > f wird zum Kopf der Funktion befördert und der tatsächlich ausgeführte Code lautet wie folgt. 🎜rrreee🎜ES6 ist völlig anders. Theoretisch erhalten Sie „Ich bin draußen!“. Da im Bereich auf Blockebene deklarierte Funktionen let ähneln, haben sie außerhalb des Bereichs keine Auswirkungen.
Wenn Sie jedoch den obigen Code tatsächlich im ES6-Browser ausführen, wird ein Fehler gemeldet. Warum ist das so? 🎜rrreee🎜Der obige Code meldet einen Fehler im ES6-Browser. 🎜🎜Es stellt sich heraus, dass eine Änderung der Verarbeitungsregeln für im Bereich auf Blockebene deklarierte Funktionen offensichtlich große Auswirkungen auf den alten Code haben wird. Um die daraus resultierenden Inkompatibilitätsprobleme zu lindern, schreibt ES6 vor, dass Browser-Implementierungen die oben genannten Vorschriften nicht einhalten können und ein eigenes Verhalten aufweisen. 🎜
  • Ermöglicht die Deklaration von Funktionen im Bereich auf Blockebene.
  • Funktionsdeklaration ähnelt var, das heißt, sie wird an den Anfang des globalen Bereichs oder Funktionsbereichs befördert.
  • Gleichzeitig wird die Funktionsdeklaration auch an den Kopf des Bereichs auf Blockebene befördert, in dem sie sich befindet.
🎜Beachten Sie, dass die oben genannten drei Regeln nur für Browser-Implementierungen von ES6 gelten. Implementierungen in anderen Umgebungen müssen weiterhin nicht berücksichtigt werden als let handle. 🎜🎜Gemäß diesen drei Regeln verhalten sich in der ES6-Umgebung des Browsers im Bereich auf Blockebene deklarierte Funktionen ähnlich wie in var deklarierte Variablen. Der Code, der das obige Beispiel tatsächlich ausführt, lautet wie folgt. 🎜rrreee🎜Angesichts der Tatsache, dass das durch die Umgebung verursachte Verhalten zu unterschiedlich ist, sollte die Deklaration von Funktionen im Bereich auf Blockebene vermieden werden. Wenn es wirklich notwendig ist, sollte es als Funktionsausdruck und nicht als Funktionsdeklarationsanweisung geschrieben werden. 🎜
// 块级作用域内部的函数声明语句,建议不要使用
{
  let a = 'secret';
  function f() {
    return a;
  }
}
 
// 块级作用域内部,优先使用函数表达式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}
Nach dem Login kopieren
Nach dem Login kopieren

ES6 的块级作用域必须有大括号

如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

// 第一种写法,报错
if (true) let x = 1;
 
// 第二种写法,不报错
if (true) {
  let x = 1;
}
Nach dem Login kopieren
Nach dem Login kopieren

上面代码中,第一种写法没有大括号,所以不存在块级作用域,而let只能出现在当前作用域的顶层,所以报错。第二种写法有大括号,所以块级作用域成立。

函数声明也是如此,严格模式下,函数只能声明在当前作用域的顶层。

// 不报错
'use strict';
if (true) {
  function f() {}
}
 
// 报错
'use strict';
if (true)
  function f() {}
Nach dem Login kopieren
Nach dem Login kopieren

【推荐学习:javascript视频教程

Das obige ist der detaillierte Inhalt vonZählt die in es6 eingeschlossene Variable als innerhalb des Blocks?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage