一、块级作用域与嵌套、let、暂时性死区
admin
2024-05-01 19:29:35
0

ES6+前导以及回忆知识

有些浏览器不兼容ES6+语法:

解决方案:ES6+ ——编译器(例如babel)——> ES5

而babel这种工具需要包管理工具,例如npm来安装。(这里包package代表代码块/功能块)。

而npm只能在node环境中实现;node也是能运行js代码的环境。

共享包:git工具,代码管理工具。


函数执行前预编译过程:AO,即生成函数上下文过程:

  1. 寻找函数形参和变量声明提升
  2. 把实参赋值给形参
  3. 寻找函数声明,赋值函数体
  4. 然后执行函数。(不属于预编译过程,执行完毕AO完整)

函数的参数相当于函数内部声明的变量;

一、块级作用域与嵌套、let、暂时性死区

解决变量污染的原则:KISS原则,keep it simple,stupid。

结论先行:let本质就是为了js增加一个块级作用域。

块级作用域形式上模样:{...}

1.1 let在同一作用域下不可重复声明

同一作用域:块级作用域,函数作用域,全局作用域。

注:块级作用域是他们的子集。

重复声明的例子:

// Uncaught SyntaxError: Identifier 'a' has already been declared
let a = 1;
let a = 2;// Uncaught SyntaxError: Identifier 'a' has already been declared
function test(){let b = 1;var b = 2;
}
test();

函数中的参数相当于在函数内部声明的变量,违反let在同一作用域下不能重复声明的原则。

// Identifier 'a' has already been declared
function test(a){let a = 1;
}
test();

1.2 let不会声明提升,会产生一个暂时性死区

let不会声明提升,在let声明之前会产生暂时性死区,即无法访问这个变量。

TDZ:temporal DeaD Zone 暂时性死区

声明提升是在预编译的过程中,无论是在函数预编译还是全局预编译。

console.log(a); //undefined
var a = 10;// Uncaught ReferenceError: Cannot access 'b' before initialization
console.log(b);
let b = 2;// Uncaught ReferenceError: Cannot access 'b' before initialization
function test(){console.log(b);let b = 2;
}
test();

再举一个ES6暂时性死区问题:

// Uncaught ReferenceError: Cannot access 'y' before initialization
function test(x = y, y = 2){console.log(x,y);
}
test();

暂时性死区导致typeof不再安全:

console.log(typeof(a)); //undefined// Uncaught ReferenceError: Cannot access 'b' before initialization
console.log(typeof(b));
let b;

1.2 let只能在当前作用域下生效

遵守了let在同一作用域下不可重复声明的原则,同时只在当前块级作用域之内生效。

function test(a){{let a = 10;}console.log(a);
}test();//undefined

let只能在当前作用域下生效:

// 例1:Uncaught ReferenceError: b is not defined
{let b = 1;
}
console.log(b);// Uncaught ReferenceError: a is not defined
if(1){let a = 1;
}
console.log(a);// 例2:死循环,永远不会报错
for(;1;){let a = 1;
}
console.log(a);

打印0-9:

var arr = [];
// 打印0-9
for(var i = 0; i < 10; i++){arr[i] = function(){console.log(i);}
}
for(var i = 0; i < 10; i++){arr[i]();
}

打印10个10:

var arr = [];
for(var i = 0; i < 10; i++){arr[i] = function(){console.log(i);}
}
for(var j = 0; j < 10; j++){arr[j]();
}

打印0-9,与上面打印10个10不同的地方在于,for循环中使用let声明变量,原因:

let创建了块级作用域,每次循环时内部的块级作用域都会去访问外层块级作用域中的变量i,而外层块级作用域中的变量i都不同,所以打印0-9

var arr = [];
for(let i = 0; i < 10; i++){arr[i] = function(){console.log(i);}
}
for(var j = 0; j < 10; j++){arr[j]();
}

打印报错原因:

var变量提升在作用域中是逐级往外提升的;也就是说var变量逐级提升的过程中,只要和let声明的变量处在同一个作用域内,就会报错。报错原因是:let在同一作用域下不可重复声明。

// 打印报错:Uncaught SyntaxError: Identifier 'i' has already been declared
for(let i = 0; i < 10; i++){var i = 'a';console.log(i);
}

打印了10个a:let定义的变量不在同一个作用域内,即使名字相同也不是同一个变量

for(let i = 0; i < 10; i++){let i = 'a';console.log(i);
}

相当于:

{let i = 0for(; i < 10;){{let i = 'a';console.log(i);}i++;}}

内层作用域可以更改外层作用域中的let声明的变量:

if(1){let a = 1;{a = 10;console.log(a); // 10}console.log(a); // 10
}

而let定义的变量不在同一个作用域内,即使名字相同也不是同一个变量:

if(1){let a = 1;{let a = 10console.log(a); // 10}console.log(a); // 1
}

补充:

  1. ES5中函数声明的位置:顶层作用域,函数作用域。

    ES6可以在块级作用域中声明函数,浏览器可以兼容,但不推荐这样使用——>在块级作用域中使用函数表达式代替函数声明。

if(i){function test(){}
}try {function test(){}
}catch(e){function test1(){}
}

解决方案:在块级作用域中使用函数表达式代替函数声明。

try {var test = function(){}
}catch(e){var test1 = function(){}
}
  1. 块级作用域没有返回值
  2. 块级作用域等于匿名函数的立即调用 ×,首先两个是不同的概念,其次块级作用域没有返回值。
if(1){let a = 1;{(function(){a = 10;console.log(a); //10})();}console.log(a); //10
}
// ------------------------------------------------------------------
if(1){let a = 1;{(function(){var a = 10;console.log(a); //10})();}console.log(a);//1
}
// ------------------------------------------------------------------
if(1){let a = 1;{(function(){let a = 10;console.log(a); //10})();}console.log(a);//1}

相关内容

热门资讯

命运圣契霓虹翻翻乐怎么玩 命运... 命运圣契这款游戏在4月29日5点就开启了这一次的新活动,叫做媚影狂飙季,命运圣契霓虹翻翻乐怎么玩其实...
香肠派对赛博矩阵珍藏召唤活动怎... 在当前的香肠派对里面,其实大家也可以迎来最近的一次更新活动的,这一次活动当中大家可以看到的就是最新的...
交错战线蔷薇试炼怎么玩 交错战... 在交错战线这款游戏当中,目前最新的挑战活动是在4月29日维护后就会开启的,而且这个活动会一直维持到5...
望月月相沙盒有什么内容 望月月... 在《望月》的天月市,月亮可并不是单纯性的天体,而是可以驱动世界运转的核心。以城市生态、月灵活动、混沌...
望月声誉点如何获取 望月声誉点... 作为一款开放性世界角色扮演游戏,望月声誉点就成为新手迅速成长,突破战斗力瓶颈的关键资源。很多的玩家一...
从俯卧撑开始打穿次元壁怎么玩 ... 从俯卧撑开始打穿次元壁怎么玩?这款游戏就会有一个创新的模式,是实体运动加上虚拟成长。早就已经彻底颠覆...
望月月相怎么玩 望月月相玩法介... 在这一个游戏的世界中,人类和月灵就会相依共生。正在一点一点的吞噬整个都市,那么玩家所需要做的就是守护...
选技大乱斗手游上线时间 选技大... 小编在今天的这期文章里面,为各位同学带来的是选技大乱斗手游上线时间的确切消息。策略类游戏,是不少玩家...
真相只有一个手游上线时间 真相... 很多同学在最近都在问真相只有一个手游上线时间到底是什么时候,那么小编今天的文章里面就已经为你准备好了...
无尽花界雅典娜怎么获取 无尽花... 无尽花界超高颜值的女神卡牌游戏不仅可以满足颜值党们的需要,而且在这里还可以体验无限制策略战斗,上百位...