作用域以及作用域链

1. 作用域

指变量存在的范围

1.1 es6 之前

种类 全局作用域和局部作用域

全局作用域

除函数大括号外都属于全局作用域

  • 变量在整个程序中一直存在
  • 定义在全作用域中的变量,任何地方都能访问

函数作用域(局部作用域)

定义函数时,在函数内部定义的变量就属于局部作用域

  • 定义在函数内部的变量,只能在函数内部进行访问
function f1() {
    var i = 9;
    console.log("输出111:",i);
}
f1();
console.log("输出222:",i);

“局部作用域”

1.2 ES6之后

种类 全局作用域,局部作用域,块级作用域

全局作用域:

  • 定义在全局作用域中的变量,任何地方都能访问

函数作用域

定义函数时,大括号里面的就是局部作用域

  • 定义在局部作用域的变量,只能在局部作用域内访问

块级作用域

使用大括号中的代码片段都属于一个块,在大括号中定义的变量对外都是不可见的,称为块级作用域

  • 定义在块级作用域的变量,只能在块级作用域内访问,在大括号外不能访问
{
    let a = 999;
    console.log("输出a的值111:", a);
}
console.log("输出a的值222:", a);

块级作用域

1.3 变量作用域

定义变量的方式(2 种):

  • es6 以前:var 变量名称
  • es6 开始: let 变量名称

两种定义方式区别

  • var 定义变量:

    同一作用域内,var 定义的变量名能够重复

    存在变量提升,能够先使用变量,再定义

  • let 定义变量

    同一作用域内,let 定义的变量名能够重复

    不存在变量提升,变量必须先定义,再使用

局部变量和全局变量

局部变量 在局部作用域内声明的变量,从定义那行开始,到大括号结束为止。

全局变量 在全局作用域内声明的变量,从定义那行开始,在整个程序中都能使用

  • es6 后增加了块级作用域,在块级作用域中使用 let 声明的变量依然属于局部变量
  • 在块级作用域中使用 var 声明的变量属于全局变量

无论在块级作用域还是函数作用域,省略 let 和 var 声明的变量默认属于全局变量

function f1() {
  n = 3333;
}
f1(); //需要运行函数f1,才会在内存中存储函数,才能找到函数内的变量n
console.log("n=", n); // n=3333;

因为 n 没有属于 let 或者 var 定义,属于全局变量,所以能够在函数外访问到

1.4 函数作用域:变量只在函数内部存在

定义:

  • 在函数内部定义的变量属于局部变量,在函数执行完毕,被垃圾回收机制回收。
  • 在函数内部,能够读取函数外的全局变量,反之不行。

函数自身的作用域

函数自身也有作用域,函数的作用域是其声明时所在的作用域,不是其调用时所在的作用域。

function f1() {
  var num = 111;
  function f2() {
    console.log("num=", num);
  }
return f2;
}

 var res= f1();
 var num=222;
 res();//111

因为函数f2定义在函数f1的内部,所以函数f2的作用域绑定在f1上,所以执行f1返回函数f2,
执行f2时,变量的取值会去函数f2所在的作用域即函数f1内部查找num,所以num取值时111

  var num = 111;
    function f2() {
      console.log("num=", num);
    }
    function f1() {
      var num = 222;
      f2();
    }
    
   f1();// num=111

函数作用域

因为函数f2的作用域在函数f1的外层,所以函数f2中输出num值在f1的外层查找,所以num值=111,
不会取f1内的num值222

2.作用域链

当查找一个变量时,默认会在当前作用域范围查找;如果未找到,就会向父级进行查找;
如果到父级未找到,会继续向上级进行查找,直到找到全局作用域为止;如果找到全局作用域还是未找到,就报错。

  • 在当前作用域查找到变量,就使用当前作用域的变量
function f1() {
  var num = 111;
  function f2() {
    var num = 222;
    console.log("num=", num);
  }
  f2();
}

f1(); //num=222

因为在函数 f2 内部存在变量 num,所以输出 f2 函数作用域内的 num=222;

  • 当前作用域为找到,会去上级作用域查找
function f1() {
  var num = 111;
  function f2() {
    console.log("num=", num);
  }
  f2();
}

f1(); //num=111
  • 顺着作用域链,依次向上一级进行查找,直到找到全局作用域
var num = 999;
function f1() {
  function f2() {
    console.log("num=", num);
  }
  f2();
}

f1(); //num=999
  • 如果找到全局作用域都未找到,就会报错
function f1() {
  function f2() {
    console.log("num=", num);
  }
  f2();
}

f1();

'报错'

posted @   Djjdb  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示