块级作用域内变量和函数的声明

变量声明

1.默认声明

块级作用域中默认声明的代码

  • 在执行之前不可访问
  • 执行之后会挂载到全局作用域上
  1. {
  2. /* 执行之前不可访问,报错a is not defined */
  3. console.log(window.a,a) // undefined Error:a is not defined
  4. a=10
  5. /* 执行之后会挂载到全局作用域上,window.a有值 */
  6. console.log(window.a,a) // 10 10
  7. }
  8. console.log(window.a,a) // 10 10

2.var声明

  • 在预编译阶段存在声明提升,全局作用域中存在该变量
  1. /* 预编译阶段全局作用域中可访问a变量 */
  2. console.log(window.a,a)// undefined undefined
  3. {
  4. console.log(window.a,a)//undefined undefined
  5. var a = 10;
  6. console.log(window.a,a)//10 10
  7. }
  8. console.log(window.a,a)// 10 10

3.let/const声明

如默认声明在执行前不可访问,但不存在提升至全局作用域,且不可重复声明

函数声明

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

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

1.function函数声明

块级作用域内函数声明

  • 在编译阶段将函数声明提升到全局作用域,并在全局声明为undefined
  • 同时在编译阶段也会被提升到对应块级作用域顶层
  • 块级作用域函数只有定义声明函数的那行代码执行过后,才会被映射到全局作用域
  1. /* 编译阶段函数声明提升并初始化为undefined */
  2. console.log(window.a,a) //undefined undefined
  3. {
  4. /* 编译阶段函数声明提升到对应块级作用域顶层 */
  5. console.log(window.a,a) //undefined function a(){}
  6. function a() {}
  7. /* 只有定义函数声明代码所在行执行后,才被映射到全局作用域 */
  8. console.log(window.a,a) //function a(){} function a(){}
  9. };
  10. console.log(window.a,a) //function a(){} function a(){}

1.1 块级作用域函数声明面试题一

  1. console.log(window.a,a);
  2. {
  3. console.log(window.a,a);
  4. function a() {};
  5. a = 10;
  6. console.log(window.a,a);
  7. };
  8. console.log(window.a,a);
  9. /*
  10. 输出答案:
  11. undefined undefined
  12. undefined function a(){}
  13. function a(){} 10
  14. function a(){} function a(){}
  15. */

1.2 块级作用域函数声明面试题二

  1. console.log(window.a,a);
  2. {
  3. console.log(window.a,a);
  4. a = 10;
  5. function a() {};
  6. console.log(window.a,a);
  7. };
  8. console.log(window.a,a);
  9. /*
  10. 输出答案:
  11. undefined undefined
  12. undefined function a(){}
  13. 10 10
  14. 10 10
  15. */