前端百题斩【012】——js中作用域及作用域链的真面目

简介: 前端百题斩【012】——js中作用域及作用域链的真面目

12.1 作用域


640.jpg

12.1.1 定义


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

12.1.2 分类


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


  1. 全局作用域


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


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


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

(2)最外层的函数


function testFun() {
    console.log('testFun');
}
testFun();

(3)最外层定义的变量


let val1 = 10;
const val2 = 20;
var val3 = 30;

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


val4 = 40;

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


Math.sin(Math.PI / 2);;
const date = new Date();
  1. 函数作用域


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


function test() {
    var val1 = 10;
    function fun1() {
        console.log('fun1');
    }
    console.log(val1); // 10
    fun1(); // fun1
}
test();
// console.log(val1); // val1 is not defined
// fun1(); // fun1 is not defined
  1. 块级作用域


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


// 单一括号包括的块
{}
// if语句
if (flag) {
}
// for语句
for (let i = 0; i < 10; i++) {
}
// ……


12.2 作用域链


640.jpg

12.2.1 定义


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


12.2.2 组成


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

  1. [[scope]]属性:指向父级变量对象和作用域链,也就是包含了父级的[[scope]]和AO
  2. AO:自身活动对象,也就是该执行上下文中的变量对象。

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


12.2.3 查找规则


  1. 从当前的执行作用域开始查找变量;
  2. 如果在当前作用域中找不到该变量,则向上一级进行查找;
  3. 继续向上一层查找,直到最外层的全局作用域。


12.2.4 实战


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


var val1 = 10;
function fun1() {
    var val2 = 20;
    function fun2() {
        var val3 = 30;
        console.log(val1 + val2 + val3);
    }
    fun2();
}
fun1();


640.png


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

相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发
js的作用域作用域链
【10月更文挑战第29天】理解JavaScript的作用域和作用域链对于正确理解变量的访问和生命周期、避免变量命名冲突以及编写高质量的JavaScript代码都具有重要意义。在实际开发中,需要合理地利用作用域和作用域链来组织代码结构,提高代码的可读性和可维护性。
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
2月前
|
自然语言处理 JavaScript 前端开发
[JS]作用域的“生产者”——词法作用域
本文介绍了JavaScript中的作用域模型与作用域,包括词法作用域和动态作用域的区别,以及全局作用域、函数作用域和块级作用域的特点。通过具体示例详细解析了变量提升、块级作用域中的暂时性死区等问题,并探讨了如何在循环中使用`var`和`let`的不同效果。最后,介绍了两种可以“欺骗”词法作用域的方法:`eval(str)`和`with(obj)`。文章结合了多位博主的总结,帮助读者更快速、便捷地掌握这些知识点。
37 2
[JS]作用域的“生产者”——词法作用域
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
55 5
|
2月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
84 1
|
2月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
56 4
|
2月前
|
JavaScript 前端开发
如何在 JavaScript 中实现块级作用域?
【10月更文挑战第29天】通过使用 `let`、`const` 关键字、立即执行函数表达式以及模块模式等方法,可以在JavaScript中有效地实现块级作用域,更好地控制变量的生命周期和访问权限,提高代码的可维护性和可读性。
|
2月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
183 1
|
3月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
220 14