输出3个10 :
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>let-vartitle>
- head>
- <body>
-
- <script>
-
- var a = [];
- for (var i = 0; i < 10; i++) {
- a[i] = function () {
- console.log(i);
- };
- }
- a[1](); // 10
- a[2](); // 10
-
- a[9](); // 10
- script>
- body>
- html>
原因:var是全局的
-
-
- var a =10
- var a =12
- var a =11
- console.log(a)//11
-
-
上述的等价于:var变量提升
- <script>
-
- var a = [];
- var i = 0
- a[i] = function () {
- console.log(i);
- };
- var i = 1
- a[i] = function () {
- console.log(i);
- };
- var i = 2
- a[i] = function () {
- console.log(i);
- };
- var i = 3
- a[i] = function () {
- console.log(i);
- };
- var i = 4
- a[i] = function () {
- console.log(i);
- };
- var i = 5
- a[i] = function () {
- console.log(i);
- };
- var i = 6
- a[i] = function () {
- console.log(i);
- };
- var i = 7
- a[i] = function () {
- console.log(i);
- };
- var i = 8
- a[i] = function () {
- console.log(i);
- };
- var i = 9
- a[i] = function () {
- console.log(i);//i是全局的i
- };
- var i = 10
- a[i] = function () {
- console.log(i);
- };
-
- console.log(i);//10
-
-
- a[1](); // 10
- a[2](); // 10
-
- a[9](); // 10
- script>
let-声明的变量仅在块级作用域内有效
- <script>
- var a = [];
- for (let i = 0; i < 10; i++) {
- a[i] = function () {
- console.log(i);
- };
- }
- a[1]()//1
- a[6](); // 6
- script>
等价于:
- <script>
- var a = [];
- {let i = 0
- {
- a[i] = function () {
- console.log(i);//只是当前的i
- };
- }
- }
- {let i = 1
- {
- a[i] = function () {
- console.log(i);
- };
- }
- }
- {let i = 2
- {
- a[i] = function () {
- console.log(i);
- };
- }
- }
- a[1]()//1
- a[2](); // 2
- script>
for循环有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域
-
- <script>
- for (let i = 0; i < 3; i++) {
- let i = '33';
- console.log(i);
- }
- 33
- // 33
- // 33
- script>
在代码块内,使用let命令声明变量之前,该变量都是不可用的{}内前面就算使用了var声明该变量也是不可以使用的。这在语法上,称为“暂时性死区”temporal dead zone,简称 TDZ)——前面不可以使用该变量作为全局变量。变量使用let命令声明,所以在声明之前,都属于x的“死区”,只要用到该变量就会报错。
- <script>
- var i=1
- { console.log(i)
- let i=12}
-
- script>

变量使用let命令声明,所以在声明之前,都属于变量的“死区”,只要用到该变量就会报错。但是变量不使用let声明,反而不会报错
- <script>
-
- if (true) {//代码块
- // TDZ开始——使用变量前且在代码块内就会出现TDZ暂时性死区
- tmp = 'abc'; // ReferenceError
- console.log(tmp); // ReferenceError
- let tmp; // TDZ结束
-
- }
-
- script>
- <script>
-
- if (true) {//代码块
- let tmp; // TDZ结束
- console.log(tmp); // undefined--没有赋值
- }
- script>
- <script>
-
- if (true) {//代码块
- // TDZ开始——使用变量前且在代码块内就会出现TDZ暂时性死区
-
- let tmp; // TDZ结束
- tmp = 123;
- console.log(tmp); // 123
- }
-
- script>
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
函数f()执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
- var tmp = new Date();
- function f() {
- console.log(tmp);
- if (false) {
- var tmp = 'hello world';
- }
- }
- f(); // undefined
外层代码块不受内层代码块的影响
- function f1() {
- let n = 5;
- if (true) {
- let n = 10;
- }
- console.log(n); // 5
- }
ES6 允许块级作用域的任意嵌套,上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。
- <script>
- {{{{
- {let insane = 'Hello World'}
- console.log(insane); // 报错//不在同一个块域内--变量不行
- }}}};
- script>
内层作用域可以定义外层作用域的同名变量
- <script>
- {{{{
- let insane = 'Hello World';
- {let insane = 'Hello World';}
- }}}};
- script>
ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
块级作用域内部,优先使用函数表达式,而不是函数声明 ,ES6 的块级作用域必须有大括号小括号不算,ES6 的块级作用域必须有大括号,不存在块级作用域,而let只能出现在当前作用域的顶层