javascript --- 再读作用域和闭包

执行环境:

// 定义了变量或函数有权访问的其他数据,决定了它们各自的行为
// 每个执行环境都有一个与之关联的变量对象
// 执行环境中定义的所有变量和函数都保存在这个变量中

执行环境与函数:

// 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.
// 而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境

作用域链:

// 当代码在一个环境中执行时,会创建变量对象的一个作用域链.
// 作用域链的用途:保证对执行环境有权访问的所有变量和函数的有序访问
// 作用域链的前端,始终是当前执行的代码所在环境的变量对象
// 如果这个环境是函数,则将其活动对象作为变量对象.
// 活动对象在最开始时只包含一个变量,即arguments对象.
// 作用域链中的下一个变量对象来自包含环境
// 再下一个变量对象来自下一个包含环境
// ...
// 一直延续到全局执行环境!

理解作用域链:

// 当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链
// 然后,使用arguments和其他命名参数的值来初始化函数的活动对象
// 在作用域链中,外部函数的活动对象始终处于第二位
// 外部函数的外部函数的活动对象处于第三位
// ...
// 直至作用域链终点的全局执行环境
// 一个例子
function compare(value1, value2) {if (value1 < value2) {return -1;} else if (value1 > value2) {return 1;} else {return 0;}
}
var result = compare(5, 10);// 当在全局环境中调用compare()时,会创建一个活动对象(包含arguments、value1、value2)
// 作用域链中的第一位是compare()的活动对象:arguments、value1、value2
// 作用域链中的第位则是全局变量对象:compare、result

在这里插入图片描述

// 后台的每个执行环境都有一个表示变量的对象 --- 变量对象
// 全局环境的变量对象始终存在
// 函数的局部环境变量,只在函数执行的过程中存在.
// 创建compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链保存在内部的[[Scope]]属性中
// 当调用compare()函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链
// 然后将活动对象(arguments、value1、value2)推入执行环境作用域链的前端.// 一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域.

闭包:

// 有权访问另一个函数作用域的变量的函数
// 闭包的常见方式,就是在一个函数内部创建另一个函数
// 闭包的情况有所不同
// 在另一个函数内部定义的函数会将 外部函数的活动对象添加到它的作用域链中
function createComparisonFunction(propertyName) {return function(object1, object2) {var value1 = object1[propertyNmae];var value2 = object2[propertyNmae];if( value1 < value2 ) {return -1;} else if ( value1 > value2 ) {return 1;} else {return 0;}};
}
// 在createComparisonFunction()函数内部定义的匿名函数(function(value1,value2))的作用域链中
// 实际上将会包含外部函数createComparionFunction()的活动对象
// 在匿名函数从createComparionaFuncion()中被返回后,它的作用域链被初始化为包含
// createComparionFunction()函数的活动对象和全局变量对象
// 这样,匿名函数就可以访问在createComparionFunction()中定义的所有变量.
// 更重要的是,createComparionFunction()函数在执行完毕后,其活动对象不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象

在这里插入图片描述
参考《JavaScript高级程序设计》(第3版)P73~P74、 P178~P180

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DOM-15/16【实战】鼠标行为预测技术

鼠标预测行为动作复杂&#xff0c;使用事件代理得不偿失&#xff0c;在数量有限的情况下&#xff0c;使用循环绑定更好用户从menu斜着向右下角滑入时&#xff0c;可能是进入main&#xff0c;也可能是要选择子菜单&#xff0c;在判断前先做延迟如何判断用户进入main的意图&#…

SQLMAP命令详解

1.基础信息 python sqlmap/sqlmap.py -u "http://url/news?id1" --current-user #获取当前用户名称 python sqlmap/sqlmap.py -u "http://www.xxoo.com/news?id1" --current-db #获取当前数据库名称 python sqlmap/sqlmap.py -u "http://www.xxoo.…

Nginx命令大全

sudo nginx #打开 nginx nginx -s reload|reopen|stop|quit #重新加载配置|重启|停止|退出 nginx nginx -t #测试配置是否有语法错误nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]-?,-h : 打开帮助信息 -v : 显示版本信…

ES6-1 ES6版本过渡历史

一 历史 HTML HTML 1, HTML 2, HTML 3 1991-1997 IETF(the Internet Engineering Task Force) 国际互联网工程任务组1997.1 HTML3.2 W3C JavaScript 1995 liveScript(后改名为JavaScript1996年改名)1996 javascript 1.0 1.1;1997 Jscript1997.6 ECMAScript 1.01998.6 ECMAS…

oracle 数据库查询 COALESCE字符函数

功能&#xff1a;返回其参数中的第一个非空表达式&#xff0c;当你要在n个字段中选取某一个非空值 coalesce函数返回参数&#xff08;列名&#xff09;中第一个非NULL的字段值&#xff0c;注意不是为空 select COALESCE(t1.a ,t2.a) as a from table_a t1left join table_b t2…

Django-model进阶

知识预览 QuerySet中介模型查询优化extra整体插入回到顶部QuerySet 可切片 使用Python 的切片语法来限制查询集记录的数目 。它等同于SQL 的LIMIT 和OFFSET 子句。 1>>> Entry.objects.all()[:5] # (LIMIT 5)>>> Entry.objects.all()[5:10] # (OFFSE…

vue --- 修饰符.lazy、.number、.trim

.lazy: 会在转变为change事件中同步 <div id"app"><input type"text" v-model.lazy"message"><p>{{ message }}</p> </div> <script>const app new Vue({el:#app,data: {message: }}) </script> //…

ES6-2 块级作用域与嵌套、let、暂行性死区

注意&#xff0c;写在开头 function test(x 1) {var x // 不报错console.log(x) } function test1(x 1) {let x 10 // 报错console.log(x) }let的变量名不可以和参数中的名称相同。而var并不限制&#xff0c;说白了就是希望你规范使用变量名。 形参原则上数组函数内部的临…

常用的操作系统知识

为什么要有操作系统 现代计算机系统是由一个或者多个处理器&#xff0c;主存&#xff0c;磁盘&#xff0c;打印机&#xff0c;键盘&#xff0c;鼠标显示器&#xff0c;网络接口以及各种其他输入&#xff0c;输出设备组成的复杂系统&#xff0c;每位程序员不可能掌握所有系统实现…

vue --- 使用中央事件总线(bus)实现跨组件通信

使用Bus实现跨组件传输须注意以下3点: 1.需要创建一个空的Vue实例(bus),来作为中间站 2.使用bus.emit来发送事件3.使用bus.emit来发送事件 3.使用bus.emit来发送事件3.使用bus.on来监听事件(在钩子created中监听) 代码如下: <!DOCTYPE html> <html> <head>…

Execution Order of Event Functions, unity 3d 事件函数的执行顺序

vs_Community.exe --layout "F:\linson\vs2017 comm\offline" --lang zh-CN 学习unity3d&#xff0c;感觉事件顺序很重要。就翻译一下官方文档吧。 Execution Order of Event Functions 事件函数的执行顺序 In Unity scripting, there are a number of event functio…

ES6-3 let进阶、const、全部变量与顶层对象

一 const 1. 定义常量 1.1 引入模块时 const test require(http)1.2 定义时必须赋值(初始化)且不可修改 const a; // Uncaught SyntaxError: Missing initializer in const declaration若赋值为原始值&#xff0c;不可修改若赋值为引用值&#xff0c;对于的地址不可修改&a…

前后端如何通信

目录 前后端如何通信URL . URI . URN第一部分&#xff1a;传输协议第二部分&#xff1a;域名第三部分&#xff1a;端口号第四部分&#xff1a;请求资源文件的路径名称第五部分&#xff1a;问号传参第六部分&#xff1a;HASH值前后端如何通信 前段&#xff1a;客户端 后端&#…

vue --- 获取子组件数据的一个应急方案$refs

使用$refs需要注意以下2点: 1.html方法使用子组件时,需使用ref “xxx” 声明. 2.在父组件中使用,this.refs.xxx.msg 获取数据 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> </head> <body><div id"app"…

Mysql 根据出生日期计算年龄

最近因为业务要求需要根据出生日期计算年龄&#xff0c;在网上查了好多的方法&#xff0c;在这里总结一下。 网上的计算方法好多都提到了格里高利历法&#xff0c;特意去查了下资料&#xff0c;普及点知识。 格里高利历是公历的标准名称&#xff0c;是一种源自于西方社会的历法…

ES6-4/5 解构赋值、函数默认值、数组解构、对象解构

ES-4 解构赋值、函数默认值、数组解构、对象解构 ES-5 隐式转换、函数参数解构、解构本质、()用法 一 解构赋值 1 虚值 含义&#xff1a;在Boolean转换结果为假的值falsy 2 函数默认值 ES6 内部使用严格相等运算符&#xff08;&#xff09;&#xff0c;判断一个位置是否有值…

springboot之session、cookie

1- 获取session的方案 session: https://blog.csdn.net/yiifaa/article/details/77542208 2- session什么时候创建&#xff1f; 一个常见的误解是以为session在有客户端访问时就被创建&#xff0c;然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样…

echarts --- 多折线图按段显示颜色规则订制

描述: 图中有4个序列,序列1和序列2在同一个x轴下,显示不同的颜色.(如,在-40到-30,序列一是红色,而序列2是黑色) 关键: VisualMap中的seriesIndex属性(根据不同的系列,制定不同的颜色规则). 下面是代码,可以直接复制到 echart实例 中进行调试 var symbolSize 20; var data [[…

Git-分布式版本控制系统

一、版本控制 版本控制系统是记录若干文件内容变化&#xff0c;以便将来查阅修订特定版本或还原部分文件的系统 分为&#xff1a;集中式版本控制系统&#xff08;svn&#xff09;简称cvcs 都有一个单一集中管理服务器&#xff0c;保存所有文件修订版本&#xff0c;开发人员通…

ES6-6 - this指向、箭头函数基本形式、rest运算符

一 chrome断点调试 观察函数调用栈 // 25min var x 1; function foo(x, y function () { x 2; console.log(2) }) {var x 3;y();console.log(x) } foo() console.log(x) // 2 3 1var x 1; function foo(x, y function () { x 2; console.log(x) }) {x 3;y();console.…