块级上下文

1.ES6中的块级上下文 “代码执行期间产生的”

除“函数和对象”的大括号之外【不算块级上下文】

2.块级上下文解释:

「例如:判断体/循环体/代码块…」才算 ,如果在大括号中出现了 let/const/function【有特殊性】/class 等关键词声明变量,则当前大括号会产生一个“块级私有上下文”;它的上级上下文是所处的环境;

  1. let/const/function/class会产生块级上下文,也会受到块级上下文的束缚
  2. var不产生,也不受块级上下文的影响
  3. 在块级私有上下文外面访问不到里面的变量 块级私有上下文也可以进行嵌套

遇到大块号 大括号中有let/const/function/class 产生块级私有上下文

EC(Block)

VO(Block) 块级私有变量对象

代码执行前的操作

1.初始化作用域链

<自己上下文,<在哪执行创建的出来的块级上下文上级上下文就是谁>>
<EC(Block),<EC(G)>>

2.变量提升

最开始 function 只声明
进入块级上下文中的第一件事情是“变量提升:声明+赋值”

console.log(a,b,c);//=>报错 报错 undefined
{
    console.log(a,b,c);//=>报错 报错 undefined
    let a = 12;
    const b = 13;
    var c = 14;
    console.log(a,b,c);//12 13 14
}
console.log(a,b,c);//报错 报错 14
复制代码

4.png

3.function函数在块级上下文中的特殊性

{新版本和老版本的不同}

老版本:

不会有块级上下文,所以在大括号(初函数和对象外)中出现function,还是保持原始的样子,变量提升阶段是声明+定义的;

新版本:

为了兼容ES5也可以兼容ES6,则全局下也要声明,私有块级上下文中也要声明;
复制代码
    1. 出现在“除函数/对象”以外的大括号中的function,在最开始变量提升阶段只声明 function
    1. 会产生块级上下文,并且进入块级上下文中的第一件事情是“变量提升:声明+赋值”function fn={}

4-1.png

4.循环体中的块级上下文

var 循环的特点

变量提升 所以i 和item都是全局的

/*
 * EC(G)
 *   i
 *   arr
 *   item
 * 变量提升:var i; var arr; var item; var不会产生块级私有上下文
 */
var arr = [10, 20, 30];
for (var i = 0; i < arr.length; i++) {
	//第一次循环 全局item=10
  //第二次循环 全局item=20
  //第三次循环 全局item=30
   var item = arr[i];
}
console.log(i, item); //3 30
//i是全局的i item也是全局的
复制代码

let方式的循环

循环体 会产生块级上下文

循环3轮 会形成4个私有上下文
let i = 0; i < arr.length; i++ 这一部分会形成父块级私有上下文:用来控制循环
 +EC(BlockParent)
 +VO(BlockParent)
私有变量:i
0  1  2  3(循环结束)
每一轮循环都会产生一个新的块级私有上下文
@1并且每一个私有的块级上下文中,都有一个私有变量"i" 存储的值就是当前循环i的值
@2私有的变量i 父级的此值会给私有的变量i 
@3每一轮循环结束,会把当前私有块中的值,同步给"父块一份" 
复制代码
/*
 * EC(G)
 *   arr --> 0x000
 * 变量提升:-- 没有
 */
let arr = [10, 20, 30];
for (let i = 0; i < arr.length; i++) {
    let item = arr[i];//无论有没有这段 都会产生新的私有块级上下文
}
console.log(i, item); //Uncaught ReferenceError: i is not defined  i/item不是全局变量
复制代码

6.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享