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.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, ECMAScript Version 6, Dell G3-Computer.
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()
{ var a = 1 console.log(a) // 1 } console.log(a) // 1 // 通过var定义的变量可以跨块作用域访问到。
第二种场景:用来计数的循环变量泄漏为全局变量
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);
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);
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() // 块级作用域之间相互不影响
ES6 允许块级作用域的任意嵌套。
{{{{ { let fnn = 'Hello' } console.log(fnn); // 报错 }}}};
上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。
{{{{ let fnn = 'Hello'; { let fnn = 'Hello' } }}}};
块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE
)不再必要了。
// IIFE 写法 (function () { var tmp = '...'; // ... }()); // 块级作用域写法 { let tmp = '...'; // ... }
ES5
规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
// 情况一 if (true) { function f() {} } // 情况二 try { function f() {} } catch(e) { // ... }
上面两种函数声明,根据 ES5
的规定都是非法的。
但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。
ES6
引入了块级作用域,明确允许在块级作用域之中声明函数。ES6
规定,块级作用域之中,函数声明语句的行为类似于 let
,在块级作用域之外不可引用。
function f() { console.log('I am outside!'); } (function () { if (false) { // 重复声明一次函数f function f() { console.log('I am inside!'); } } f(); }());
上面代码在 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(); }());
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
上面的代码在 ES6
浏览器中,都会报错。
原来,如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式
var
,即会提升到全局作用域或函数作用域的头部。注意,上面三条规则只对 ES6
的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作 let
处理。
根据这三条规则,浏览器的 ES6
环境中,块级作用域内声明的函数,行为类似于 var
// 浏览器的 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
// 块级作用域内部的函数声明语句,建议不要使用 { let a = 'secret'; function f() { return a; } } // 块级作用域内部,优先使用函数表达式 { let a = 'secret'; let f = function () { return a; }; }
var
in der for
-Schleife definiert wurden, kann im externen Bereich🎜// 第一种写法,报错 if (true) let x = 1; // 第二种写法,不报错 if (true) { let x = 1; }
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() {}
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>if
deklariert 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. 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. 🎜var
, das heißt, sie wird an den Anfang des globalen Bereichs oder Funktionsbereichs befördert. 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; }; }
如果没有大括号,JavaScript
引擎就认为不存在块级作用域。
// 第一种写法,报错 if (true) let x = 1; // 第二种写法,不报错 if (true) { let x = 1; }
上面代码中,第一种写法没有大括号,所以不存在块级作用域,而let只能出现在当前作用域的顶层,所以报错。第二种写法有大括号,所以块级作用域成立。
函数声明也是如此,严格模式下,函数只能声明在当前作用域的顶层。
// 不报错 'use strict'; if (true) { function f() {} } // 报错 'use strict'; if (true) function f() {}
【推荐学习: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!