文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

前端百题斩——JS中作用域及作用域链的真面目

2024-12-03 04:24

关注

12.1.1 定义

作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。简言之作用域就是变量与函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。

12.1.2 分类

在ES6阶段之前,作用域分为两种:全局作用域和函数作用域;进行ES6之后,作用域分为:全局作用域、函数作用域和块级作用域。

全局作用域

在该作用域中的对象在代码的任何地方都能访问,其生命周期伴随着页面的生命周期。例如以下内容均在全局作用域中。

(1)window上的属性(在浏览器中)

  1. console.log(window.location.href); // 页面地址 

(2)最外层的函数

  1. function testFun() { 
  2.     console.log('testFun'); 
  3.  
  4. testFun(); 

(3)最外层定义的变量

  1. let val1 = 10; 
  2. const val2 = 20; 
  3. var val3 = 30; 

(4)未定义直接赋值的变量

  1. val4 = 40; 

(5)js规定的全局对象的属性,三个值(Infinity、NaN、undefined)、九个函数(parseInt、parseFloat、decodeURI、encodeURI……)、一些构造器(Date、Array等)、四个用于当做命名空间的对象(Atomics、JSON、Math、Reflect)。

  1. Math.sin(Math.PI / 2);; 
  2. const date = new Date(); 

函数作用域

在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。在函数执行结束之后,函数内部定义的变量会被销毁。

  1. function test() { 
  2.     var val1 = 10; 
  3.     function fun1() { 
  4.         console.log('fun1'); 
  5.     } 
  6.     console.log(val1); // 10 
  7.     fun1(); // fun1 
  8. test(); 
  9. // console.log(val1); // val1 is not defined 
  10. // fun1(); // fun1 is not defined 

块级作用域

在ES6阶段,出现了块的概念,新增了块级作用域,同时新增了let、const命令。块级作用域简言之就是使用一对大括号{}包裹的一段代码,通过单独的大括号、if块、while块、for块、try/catch/finallyd等都会产生块级作用域。(对于let和const在块级作用域的特征可见前端百题斩【002】)

  1. // 单一括号包括的块 
  2. {} 
  3.  
  4. // if语句 
  5. if (flag) { 
  6.  
  7.  
  8. // for语句 
  9. for (let i = 0; i < 10; i++) { 
  10.  
  11.  
  12. // …… 

12.2 作用域链

12.2.1 定义

在每个执行上下文的变量环境中,都包含一个外部引用(成为outer),用来指向外部的指向上下文。当在查找一个变量的时候,如果在当前的变量环境中没有找到,js引擎会继续在outer所指向的执行上下文中查找,把这个查找的链条称为作用域链。(作用域链可以理解为一组对象列表,包含 父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数。)

12.2.2 组成

作用域链由两部分组成,分别是[[scope]]属性和AO。

[[scope]]属性:指向父级变量对象和作用域链,也就是包含了父级的[[scope]]和AO

AO:自身活动对象,也就是该执行上下文中的变量对象。

扩展:如此 [[scope]]包含[[scope]],便自上而下形成一条 链式作用域。

12.2.3 查找规则

12.2.4 实战

下面用一个简单的例子来演示该作用域链,以进一步理解作用域链。

  1. var val1 = 10; 
  2. function fun1() { 
  3.     var val2 = 20; 
  4.     function fun2() { 
  5.         var val3 = 30; 
  6.         console.log(val1 + val2 + val3); 
  7.     } 
  8.     fun2(); 
  9.  
  10. fun1(); 

 

结合代码和上述执行上下文的流程图,当执行到console.log(val1 + val2 + val3);时会在fun2函数作用域中找到val3变量,在fun1函数作用域中找到变量val2,在全局作用域中找到变量val1,最终与该语句相关的三个变量均获取到。其中fun2函数作用域、fun1函数作用域、全局作用域就构成了一条作用域链。

本文转载自微信公众号「执鸢者」,可以通过以下二维码关注。转载本文请联系执鸢者公众号。

 

来源:执鸢者内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯