位置: 编程技术 - 正文

浅析JavaScript作用域链、执行上下文与闭包(javascript设计的初衷和特点)

编辑:rootadmin

推荐整理分享浅析JavaScript作用域链、执行上下文与闭包(javascript设计的初衷和特点),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:细说javascript,javascript设计的初衷和特点,简述javascript,javascript的作业,简述javascript的作用,简述javascript的作用,javascript的作业,简述javascript,内容如对您有帮助,希望把文章链接给更多的朋友!

闭包和作用域链是JavaScript中比较重要的概念,这两天翻阅了一些资料,把相关知识点给大家总结了以下。

JavaScript 采用词法作用域(lexical scoping),函数执行依赖的变量作用域是由函数定义的时候决定,而不是函数执行的时候决定。以下面的代码片段举例说明,通常来说(基于栈的实现,如 C 语言) foo 被调用之后函数内的本地变量 scope 会被释放,但是从词法上看 foo 的内嵌匿名函数中 scope 应该指的是 foo 的本地变量 scope ,并且实际上代码的运行结果跟词法上的表达式一致的,f 被调用之后返回的是local scope。函数对象 f 在其主体函数 foo 调用结束之后,依然保持着 foo 函数体作用域变量的引用,这就是所谓的闭包 。

那么闭包到底是如何工作的呢?了解闭包首先需要了解变量作用域和作用域链,另外一个重要的概念是执行上下文环境。

变量作用域

JavaScript 中全局变量拥有全局的作用域,函数体内申明的变量的作用域是整个函数体内,是局部的,当然也包括函数体内定义的嵌套函数。函数体内局部变量的优先级高于全局变量,如果局部变量与全局变量重名,全局变量会被局部变量掩盖;同样嵌套函数内定义的局部变量的优先级高于嵌套函数所在函数的局部变量。这简直是显而易见的,几乎所有人都了解。接下来谈谈可能大家比较陌生的。

函数声明提升

用一句话来说明函数申明提升,指的是函数体内部申明的变量再整个函数内有效。也就是说,就是在函数体最底部申明的变量,也会被提升到最顶部。举个例子:

第一个console.log(scope)会打印出undefined而不是global scope,是因为局部变量的申明被提升了,只是还未赋值。

作为属性的变量

在 JavaScript 中,有三种定义全局变量的方式,如下示例代码中的 globalVal1 、globalVal2 和 globalValue3 。一个有趣的现象是,实际上全局变量仅仅只是全局对象 window/global (在浏览器中是 window,在 node.js 中是 global)的属性而已。为了更加符合通常意义的变量定义, JavaScript 把用 var 定义的全局变量,设计成了不可删除的全局对象属性。 通过Object.getOwnPropertyDescriptor(this, 'globalVal1')可以得到,其 configurable 属性为 false 。

浅析JavaScript作用域链、执行上下文与闭包(javascript设计的初衷和特点)

那么问题来了,函数体内定义的局部变量是不是也作为某个对象的属性呢?答案是肯定的。这个对象是跟函数调用相关的,在 ECMAScript 3中称为“call object”、ECMAScript 5中称为“declaravite environment record”的对象。这个特殊的对象对我们来说是一种不可见的内部实现。

作用域链

从上一节我们知道,函数局部变量可与看做是某个不可见的对象的属性。那么 JavaScript 的词法作用域的实现可以这样描述:每一段 JavaScript 代码(全局或函数)都有一个跟它关联的作用域链,它可以是数组或链表结构;作用域链中的每一个元素定义了一组作用域内的变量;当我们要查找变量 x 的值,那么从作用域链的第一个元素中找这个变量,如果没有找到者找链表中的下一个元素中查找,直到找到或抵达链尾。了解作用域链的概念对理解闭包至关重要。

执行上下文

每段 JavaScript 代码的执行都与执行上下文绑定,运行的代码通过执行上下文获可用的变量、函数、数据等信息。全局的执行上下文是唯一的,与全局代码绑定,每执行一个函数都会创建一个执行上下文与其绑定。JavaScript 通过栈的数据结构维护执行上下文,全局执行上下文位于栈底,当执行一个函数的时候,新创建的函数执行上下文将会压入栈中,执行上下文指针指向栈顶,运行的代码即可获得当前执行的函数绑定的执行上下文。如果函数体执行嵌套的函数,也会创建执行上下文并压入栈,指针指向栈顶,当嵌套函数运行结束后,与它绑定的执行上下文被推出栈,指针重新指向函数绑定的执行上下文。同样,函数执行结束,指针会指向全局执行上下文。

执行上下文可以描述成式一个包含变量对象(对应全局)/活动对象(对应函数)、作用域链和 this 的数据结构。当一个函数执行时,活动对象被创建并绑定到执行上下文。活动对象包括函数体内申明的变量、函数、arguments 等。作用域链在上一节以及提到,是按词法作用域构建的。需要注意的是 this 不属于活动对象,在函数执行的那一刻就以及确定。执行上下文的创建是有特定的次序和阶段的,不同阶段有不同的状态,具体的细节可以看一下参考资料,在结尾部分会列出。

闭包

了解了作用域链和执行上下文,回过头看篇首的那段代码,基本上就可以解释闭包式如何工作了。函数调用的时候创建的执行上下文以及词法作用域链保持函数调用所需要的信息, f 函数调用之后才可以返回local scope。

需要注意的是,函数内定义的多个函数使用的是同一个作用域链,在使用 for 循环赋值匿名函数对象的场景比较容易引起错误,举例如下:

arr[0].func()返回的是 而不是 0,跟感官上的语义有偏差。在 ECMAScript 6 引入 let 之前, 变量作用域范围是在整个函数体内而不是在代码区块之内,所以上面的例子中所有定义的 func 函数引用了同一个作用域链在 for 循环之后, i 的值已经变为 。

正确的做法是这样:

以上内容给大家介绍了JavaScript作用域链、执行上下文与闭包的相关知识,希望对大家有所帮助。

理解javascript中的严格模式 一、什么是严格模式我们平时写的JavaScript代码一般都运行在正常模式中的,除了正常运行模式,ECMAscript5添加了第二种运行模式:严格模式(strictmode)

基于JavaScript判断浏览器到底是关闭还是刷新(超准确) 本文是小编总结的一些核心内容,个人感觉对大家有所帮助,具体内容请看下文:页面加载时只执行onload页面关闭时只执行onunload页面刷新时先执行onbefo

基于JavaScript实现动态添加删除表格的行 又一个动态控制表格的效果,用JavaScript动态生成表格行、表格列,以及还可动态删除这些行列,行等,运行代码后,点击对应的功能按钮,即可实现对

标签: javascript设计的初衷和特点

本文链接地址:https://www.jiuchutong.com/biancheng/381694.html 转载请保留说明!

上一篇:js格式化输入框内金额、银行卡号(js格式化输出数字)

下一篇:理解javascript中的严格模式(js怎么理解)

  • 会计新手如何学会收款流程
  • 视同销售收入是纳税调整项目吗?
  • 公积金贷款金额少怎么办
  • 固定资产盘点折旧怎么算
  • 公户购买理财怎么做账
  • 劳务费属于印花税范围吗
  • 暂估材料收到发票后是更正还是红冲
  • 小规模纳税人租金发票的税率是多少
  • 发票没交税可以退税吗
  • 研发投入和研发支出的关系
  • 对公账户取现金有限制吗
  • 对公账户发工资1万要交税吗
  • 房地产企业汇缴清算条件
  • 个人房租费收入怎么做账
  • 营改增举例说明
  • 如何理解递延所得税资产和负债计算
  • 暂估应付账款借方余额
  • 某企业月末由仓库转来发料凭证汇总表
  • 民事诉讼的适用范围和基本制度
  • 销项税没有进项税多
  • 单位收到增值税专用开票人写管理员
  • 代驾费开增值税专票还是普票?
  • 出售二手车税收优惠
  • 非银行支付机构条例(征求意见稿)
  • 坏账核销谁来审批
  • 水资源税计入会计科目
  • 税务没有核定印花税
  • 小规模财报是按年报吗
  • 发票有几个
  • 销项增值税普通发票
  • 亏损企业季度盈利企业所得税怎么预缴?
  • 单位为员工支付医疗费
  • 华为手机蓝牙传送照片到苹果手机
  • 如何使用腾讯电子签维护自己的权益
  • php预定义常量要使用define函数进行定义
  • 报销费用填制什么凭证
  • 买二手房避税
  • 金融企业会计第三版课后答案孟艳琼
  • 企业股权转让所得可以弥补亏损吗
  • timit数据集
  • php读取excel文件
  • win11预览版22000.51
  • 居间协议合同范本完整版
  • mysql的命名规则
  • 房地产企业样板间装修费账务处理
  • mysql出现箭头
  • 物业代收代缴是什么意思
  • 一般纳税人每月开票不能超过多少
  • 增值税留抵税额借贷方向
  • 一般纳税人增值税减免政策2023
  • 扣供应商的货款进项税要转出吗
  • 退票凭证丢了怎么办
  • 装修费还没摊销怎么办
  • 转账支票记到哪个科目
  • 账上存货太多实收怎么办
  • 进口关税,增值税,消费税
  • 跨年度费用如何计算
  • mysql必知必会读书心得
  • mysql5.5.62安装配置教程
  • mysql5.5中文乱码解决
  • 微软雅黑可以免费用吗
  • mac电脑双系统
  • win10出现
  • ubuntu20.04卸载
  • linux codec
  • win8系统咋样
  • 电脑win10显卡驱动
  • unity特效制作教程
  • es6 文档
  • linux shell终端
  • 用vue写登录页面
  • es6 new set()
  • js特殊字符有哪些
  • JavaScript的函数中只能写一条代码语句
  • jQuery使用Selectator插件实现多选下拉列表过滤框(附源码下载)
  • kraken框架
  • 广东高速公路电子发票服务来平台
  • 我是一般纳税人对方给我开的普票
  • 不动产租赁和经营租赁税率是多少
  • 浙江国地税联合电子税务局哪里看收到的发票
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设