当前位置: 首页 > news >正文

JavaScript作用域相关的总结

这里主要记录在日常中对知识的学习,通过结合笔记与自身理解的方式尝试写下总结
文章对细节可能不会一一介绍解释,内容仅作参考
复制代码

作用域指程序源代码中定义变量的区域,规定了如何查找变量即确定当前执行代码对变量的访问权限

JavaScript采用的是词法作用域,也就是函数的作用域函数定义的时候就决定
与词法作用域相反的是动态作用域,也就是函数的作用域是在函数调用的时候才决定,这里仅供了解就好


在JavaScript中主要有全局作用域函数作用域块级作用域(ES6之前没有)三个

  • 全局作用域:顾名思义,是为最顶层最大的范围
  • 函数作用域:仅在某个函数内部有效的范围
  • 块级作用域:仅在某个块级代码内部有效的范围

作用域是一个很抽象的概念,可以理解成一个地盘,具有

  • 独立性:作用域包裹起来让变量不会外泄,所以在不同作用域下同名变量不会有冲突 - 隔离变量
  • 分层与嵌套:作用域是有层级关系的,上下级关系的确定就看函数是在哪个作用域下定义的(在哪个作用域下定义就是哪个作用域的子作用域

内层作用域(子作用域)可以访问外层作用域(父作用域)的变量,反之则不行。在查找一个变量时,如果在本作用域内无定义,那么就会往上一层父作用域查找,一层一层向上直到全局作用域,这种方式就成为了作用域链


再强调一次:作用域是在相应代码定义时就被创建(例如定义函数时决定相对应的函数作用域)


举个栗子加深一下理解:

function foo() {
    var b = 2
    function bar(c) {
        var d = 3
        console.log(a, b, c, d)
    }
    bar(b * 3)
}
function hkk() {
    var e = 4
    console.log(a, e)
}
var a = 1
复制代码

假设走到这段代码的时候,最外层作用域是全局作用域,目前的作用域层级为

[全局作用域]
复制代码

定义foo函数,会有一个foo作用域产生

[全局作用域[foo作用域]]
复制代码

然后走进foo里面,定义bar函数,会有一个bar作用域产生

[全局作用域 [foo作用域 [ bar作用域 ] ] ]
复制代码

绕出来后,还定义了hkk函数,会有一个hkk作用域产生

[全局作用域 [foo作用域 [ bar作用域 ], hkk作用域]]
复制代码

在接下来变量的查找就会依赖这个作用域链 比如说在上面代码会有

  • bar -> foo -> 全局
  • hkk -> 全局

在函数执行时变量的查找就会变成这样:

function foo() {
    var b = 2
    function bar(c) {
        var d = 3
        console.log(a, b, c, d)
        // a: 在bar这里找不到,去foo那里找找。foo也找不到呢,再上去全局找找。在全局找到了 -> 最后得出这个值要在全局作用域下拿到
        // b: 在bar这里找不到,去foo那里找找。在foo找到了 -> 最后得出这个值要在foo作用域下拿到
        // c: 在bar这里找到了 -> 最后得出这个值要在bar作用域下拿到
        // d: 在bar这里找到了 -> 最后得出这个值要在bar作用域下拿到
    }
    bar(b * 3)
}
function hkk() {
    var e = 4
    console.log(a, e)
    // a: 在hkk这里找不到,上去全局找找。在全局找到了 -> 最后得出这个值要在全局作用域下拿到
    // c: 在hkk这里找到了 -> 最后得出这个值要在hkk作用域下拿到
}
var a = 1
复制代码

作用域是执行上下文知识的前置知识

可以想象成: 我要办一座学校(全局),会有多个年级(函数/块级作用域),然后呢每个年级里面又有多个班级(子函数/块级作用域),每个班级又会有跟细的组织结构

但是呢 我这里只是想好了怎么安排制度(某个班级考试时,如果班级自己没有试卷,那需要的试卷应该向对应的年级拿,年级没有,再去找学校要),但至于运行起来后,年级有多少试卷,是否还有作业,就要看年级私底下的安排了(这个这里先不去理解 看看就好)

转载于:https://juejin.im/post/5cb5e51be51d456e60003acf

相关文章:

  • 为什么SaaS软件集成是未来的必然趋势?
  • 华奥延保对代码的理解(华奥延保)
  • 《代码敲不队》第一次作业:团队亮相
  • HashMap 与 HashSet 联系
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • python游戏开发:59行代码编写飞扬的独眼鸟
  • isilon SMB 控制允许IP访问
  • D35 876. Middle of the Linked List
  • 前端常用的缓存技术
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 女程序媛与男程序猿的一天,萌萌哒!
  • Qt编写自定义控件1-汽车仪表盘
  • solr8.0 springboot整合solr(四)
  • 18.C#--for循环的正序输出和倒序输出,在屏幕上打印1 - 10正序和倒序
  • 云计算的资源管理特性及服务类型
  • egg(89)--egg之redis的发布和订阅
  • Elasticsearch 参考指南(升级前重新索引)
  • Github访问慢解决办法
  • If…else
  • magento 货币换算
  • Mybatis初体验
  • node学习系列之简单文件上传
  • 电商搜索引擎的架构设计和性能优化
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 漂亮刷新控件-iOS
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 用jquery写贪吃蛇
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • mysql面试题分组并合并列
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #stm32整理(一)flash读写
  • (4)(4.6) Triducer
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (排序详解之 堆排序)
  • (区间dp) (经典例题) 石子合并
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)socket Aio demo
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • *p++,*(p++),*++p,(*p)++区别?
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .net 验证控件和javaScript的冲突问题
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net反混淆脱壳工具de4dot的使用
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .NET下的多线程编程—1-线程机制概述
  • .NET中的Exception处理(C#)
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • [20160807][系统设计的三次迭代]
  • [ASP.NET MVC]Ajax与CustomErrors的尴尬
  • [BUG] Authentication Error