前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重学JS基础-作用域链和闭包

重学JS基础-作用域链和闭包

作者头像
Jou
发布于 2022-08-10 12:55:05
发布于 2022-08-10 12:55:05
61800
代码可运行
举报
文章被收录于专栏:前端技术归纳前端技术归纳
运行总次数:0
代码可运行

一,作用域和作用域链

1.全局作用域

JS有一个全局对象,window,在全局声明的变量都属于window的属性,未使用声明符声明的属性也是window的属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = 10;
b = 10;
function fun(){
    c = 10;
    var d = 10;
}
fun();
console.log("window.a",window.a);   //10
console.log("window.b",window.b);   //10
console.log("window.c",window.c);   //10
console.log("window.d",window.d);   //undefined

2.函数作用域

我们在定义函数的时候,函数会默认存在一个叫scope的隐式属性,即,保存着函数定义时的信息,这个属性指向一个数组,数组中存的则是一组链式的函数执行上下文。数组的第一项就是函数自身的作用域。

假如我们要访问一个属性,就在这个域中按顺序寻找。所以下面的代码只能打印出b的值,因为a在函数定义的时候并未定义。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var b = 2; 
function foo() { 
    console.log(b); 
    console.log(a); 
} 
(function () { 
    var a = 1; 
    foo(); 
})();

//2
//error

3.作用域链

上面说到函数有一个属性指向一个链式的执行上下文,最下层是函数自己的作用域,而再往上就是父级作用域,最后到达window作用域。

因为在函数被定义的时候,会直接拥有父级模块的作用域,比如在window中被定义的函数,会直接拥有window的作用域。

在函数执行的时候,假如访问某个属性在当前函数中没有,就会在链式的执行上下文中寻找。

看一下例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a=10
function fun1(){
    var b=20;
    function fun2(){
        //...
    }
    fun2();
}
fun1();

如上,通过预编译和作用域链来解读一下代码运行的具体步骤

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.首先,全局存在作用域GO,归window所有
2.定义函数fun1时,会继承window的作用域,其scope属性被创建,指向一个链表,其第一项为GO,
即scope(fun1):GO -->
2执行函数fun1时,会生成一个属于fun1的函数执行上下文AO,这是scope第一项为这个AO对象,
即scope(fun1):AO(fun1) --> GO -->
3.执行函数fun1时,在fun1函数体中,由于定义了函数fun2,所以创建fun2的scope属性,直接继承自fun1,
即scope(fun2): AO(fun1) --> GO -->
4.之后在执行函数fun2时,会创建一个专属于fun2的执行上下文,放入,fun2的scope属性的最顶端,
即scope(fun2): AO(fun2) --> AO(fun1) --> GO -->
5,执行完函数fun2后,销毁其作用域
6,执行完函数fun1后,销毁其作用域
属性访问

假如现在要在函数b中访问一个变量,系统则会到函数b的scope中去寻找,scope是一个数组,它从第0位开始访问,第一位是函数b的作用域,找不到的话会继续想下寻找,即函数a的作用域,

再找不到,便会继续向下,即在window的作用域中寻找,最后也无法找的变量的话,则会抛出错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var cc = 123;
function a(){
    function b(){
        var bb = 234;
        aa = 0;
        console.log(cc);
    }
    var aa = 123;
    var cc = 111;
    b();
    console.log(aa);       
}
a();

所以函数执行结果为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
111
0

二.闭包

当内部函数被保存到外部时,将会生成闭包。生成闭包后,内部函数依旧可以访问其所在的外部函数的作用域。

1.原理

在内部函数被定义的时候会创建一个属于内部函数的scope属性保存着的作用域链,它会直接继承父函数的作用域链.

当它有对父级函数的变量的访问时,这个作用域链在父级函数销毁时不会被销毁,此时内部函数依旧可以访问父级函数的变量。

2.避免闭包的方法

(1)立即执行函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(function(){ 
    var a; 
    //code
}());

(function(){
    var a; 
    //code
})();

但是,括号有个缺点,那就是如果上一行代码不写分号,括号会被解释为上一行代码最末的函数调用,产生完全不符合预期,并且难以调试的行为,加号等运算符也有类似的问题。

另一种写法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void function () {
    var a = 100;
    console.log(a);

}();

语义上 void 运算表示忽略后面表达式的值,变成 undefined

(2)使用const和let

3.闭包的使用

使用闭包实现一个计数器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function counterCreate(){
    var count = 0;
    return function(){
        count++;
        console.log(`计数${count}`);
    }
}
var addCount = counterCreate();
addCount();//计数1次
addCount();//计数2次
addCount();//计数3次
addCount();//计数4次

这里内部函数使用了外部函数的count属性,所以再外部函数销毁之后,count依然可以被内部函数使用,但无法再外部被访问。

4.闭包的优缺点

闭包的好处
  1. 希望一个变量长期存储在内存中
  2. 避免全局变量的污染
  3. 私有成员的存在
  4. 用于缓存闭包的坏处

容易造成内存泄漏

使用闭包定义对象的私有变量
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var Person = (function () {
var privateData = {},
  privateId = 0;
function Person(name) {
  Object.defineProperty(this, "_id", { value: privateId++ });
  privateData[this._id] = {
    name: name,
  };
}
Person.prototype.getName = function () {
  return privateData[this._id].name;
};
return Person;
})();
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
软件项目管理笔记
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RbSNI3en-1589334555768)(1.png)]
全栈程序员站长
2022/08/19
1.6K0
软件项目管理知识点总结
项目的定义和特征: (1)美国项目管理权威机构--项目管理协会(Project Management Institute,PMI)认为,项目是为完成某一独特的产品或服务所做的一次性努力. (2)德国DIN(德国工业标准)69901认为,项目是指在总体上符合下列条件的唯一性任务: ①具有预定的目标; ②具有时间、财务、人力和其他限制条件; ③具有专门的组织. (3)《项目管理质量指南(ISO10006)》定义项目为:“具有独特的过程,有开始和结束日期,由一系列相互协调和受控的活动组成.过程的实施是为了达到规定的目标,包括满足时间、费用和资源等约束条件”. (4)中国项目管理知识体系纲要(2002版)中对项目的定义为:项目是创造独特产品、服务或其他成果的一次性工作任务. (5)联合国工业发展组织《工业项目评估手册》对项目的定义是:“一个项目是对一项投资的一个提案,用来创建、扩建或发展某些工厂企业,以便在一定周期内增加货物的生产或社会的服务.” (6)世界银行认为:“所谓项目,一般系指同一性质的投资,或同一部门内一系列有关或相同的投资,或不同部门内的一系列投资”. (7)一般地说,所谓项目就是指在一定约束条件下(主要是限定资源、限定时间、限定质量),具有特定目标的一次性任务. 共同特征: (1)一次性 (2)独特性 (3)目标的明确性 (4)活动的整体性 (5)组织的临时性和开放性 (6)开发与实施的渐进性 常见的习题都是选出符合项目定义的事物,如:创建一个具有特定功能的软件是项目,但是日常打扫卫生就不属于项目 项目的特征: 1.有明确的目标 2.项目之间的活动具有相关性 3.限定的周期 4.有独特性 5.资源成本的约束性 6.项目的不确定性 项目与日常运作有什么不同: 1.项目是一次性的,日常运作是重复进行的 2.项目是以目标为导向的,日常运作是通过效率和有效性体现的 3.项目是通过项目经理及其团队工作完成的,而日常运作是职能式的线性管理 4.项目存在大量的变更管理,而日常运作则基本保持连贯性
全栈程序员站长
2022/08/25
1.7K0
软件项目管理知识点总结
项目管理之pmpbok6之1-7章总结
项目组合管理:便于有效管理、实现战略业务目标而结合在一起的项目、项目集和其他工作。共享资源、强调服务于组织战略对项目进行排序、实现组合资源的最大化;没有内在联系的只能当项目组合来管理。
菲宇
2019/06/12
1.5K0
项目管理之pmpbok6之1-7章总结
软件项目管理案例分析
高水平项目管理是软件项目成功的关键,也是软件产品质量的根本保证,具有这方面理论和实践的人员是目前软件组织中急需的高层次人才。为建立符合中国国情的软件开发过程和组织体系,培训中心特举办“软件项目管理案例分析”培训班,具体事宜通知如下:
全栈程序员站长
2022/08/31
9670
PMPBOK6之项目管理的33个文件
活动属性是指每项活动所具有的多重属性,用来扩充对活动的描述,活动属性随时间演进。在项目初始阶段,活动属性包括唯一活动标识 (ID)、WBS 标识和活动标签或名称;在活动属性编制完成时,活动属性可能包括活动描述、紧前活动、紧后活动、逻辑关系、提前量和滞后量(见 6.3.2.3 节)、资源需求、强制日期、制约因素和假设条件。活动属性可用于识别开展工作的地点、编制开展活动的项目日历,以及相关的活动类型。活动属性还可用于编制进度计划。根据活动属性,可在报告中以各种方式对计划进度活动进行选择、排序和分类。
菲宇
2019/06/13
1.1K0
PMPBOK6之项目管理的33个文件
项目管理之问,ChatGPT作答
I. 项目管理概述 A. 项目管理定义和目标 B. 项目管理的重要性和价值 C. 项目管理生命周期
明志德道
2023/11/26
3230
项目管理实践-技法:提升绩效与改进过程
第1章 决战项目,举起制胜武器 应对环境变化环境 主要有3种方法 学习:培训是学习别人经验教训的捷径,培训也越来越受到重视,越来越多的企业大学就是一个明证 创新:学习总是跟在人后面,总是在追随(我称其为“尾随”)。哪怕跟得再近,也无法领先。创新才是实现领先的应对策略 整合:掌握最先进技术的最简单方法,就是将掌握这种技术的人或团队“挖”过来。这就是整合,整合是应对环境变化的第三种方法 非重复性工作决定组织的发展 实现组织战略和目标的手段主要依靠两类工作,一类是持续的、重复的工作(运营),另一类是独特的
yeedomliu
2022/03/31
7060
项目管理实践-技法:提升绩效与改进过程
如何进行项目管理?
这篇文章是软件工程系列知识总结的第三篇,前面的两篇文章聊了软件工程的重要性以及相关的基础知识。这篇文章,我会将软件工程中关于项目规划和管理的重点知识进行总结梳理,并以自己理解的方式进行阐述。
老_张
2023/03/01
4890
如何进行项目管理?
三角方式是什么?如何在项目管理中应用
在项目管理领域,有许多方法和工具能够帮助项目经理更好地计划、执行和控制项目。三角方式(Project Management Triangle),也称为项目管理铁三角,是其中最经典且常用的一种方法。它的核心思想是项目的三个关键要素:范围(Scope)、时间(Time)和成本(Cost),它们构成了项目成功的基础。而项目经理的任务就是在这三个要素之间找到平衡,以确保项目顺利完成。
TENGZO
2024/10/14
1810
软件测试人员眼中的项目管理
项目感觉要延期了,若是不延期,后期加班估计会非常多,若不调整项目质量可想而知,项目过程中暴露的问题太多,推动问题解决毫无进度,如前期需求不明确需要等、任务量大、时间短(上线时间固定),究其原因是项目流程上就有问题。
王豆豆
2020/06/10
8900
说说我理解的技术项目管理
技术到了一定阶段势必会面临充当技术项目管理的角色,这个角色不仅仅要求具备技术视野和技术规划决策能力,面对庞大的组织如何运筹帷幄,拉资源拉团队干成事是技术管理者的升级打怪的必要技能,项目越复杂,越是考验项目管理者或者项目owner应对复杂多变情况的应变能力。下面结合自己工作中的经验及所见所闻谈谈我对技术项目管理的理解。
liddytang
2024/09/06
1980
项目管理之PMP需要掌握的76个成果
成果名称 内含 来自 用于 变更请求 纠正、预防、缺陷补救、更新;其状态在实施整体变更控制输出中被改变 各知识领域规划、执行、监控过程组指导与管理项目执行、监控项目工作、核实范围、控制范围、控制进度、控制成本、管理质量、管理团队、管理相关方参与、控制项目工作、监控
菲宇
2019/06/13
8560
【愚公系列】软考中级-软件设计师 042-软件工程基础(项目管理-进度管理)
进度管理对于项目的成功实施至关重要,可以帮助项目经理实现项目的按时、按质、按量完成,提高项目的效率和质量,降低项目的风险。
愚公搬代码
2024/04/23
1990
项目管理修炼之道
前言 我的藏书中有一些非常经典,如迪马可、温伯格、布鲁克斯、麦康乃尔、考克伯恩、麦卡锡还有汉弗莱写的书 从项目管理相关的教科书与PMP的培训教材里能够学到的是一个项目经理需要具备的基本技能。这些技能只能让你成为一名项目经理,但是无法让你成为优秀的项目经理,其中的差异就在于是否有实战经验的积累 并不具有对项目整个图景清晰、理智的分析和认知,没有详细考量项目的驱动因素、约束、风险等。总而言之,就是没有一套成体系的理论、方法和实践 你的项目每天都在加快节奏,你的客户变得越来越不耐烦,大家越来越不能容忍无法正常工作
yeedomliu
2021/03/16
7600
项目管理修炼之道
项目管理深入理解10--整合管理
进入最后一章,加油,这部分是之前得分最低的部分,更加要加强。这部分内容综合性很强,尤其是变更管理的过程更是最常见得考试难点。 项目经理并不承担本部分所有的项目责任,但项目经理需要对大多数项目决策和
用户1216676
2018/01/24
9100
项目管理深入理解10--整合管理
盘点:22个最好用的项目管理工具
拥有正确的工具集来处理分析、需求、变更和项目进展将帮助项目经理以最佳状态做出执行任务。
人称T客
2019/11/22
6K0
盘点:22个最好用的项目管理工具
【PMP】四、项目整合管理
项目整合管理是项目管理的核心,是为了实现项目各要素之间的相互协调,并在相互矛盾,相互竞争的目标中寻找最佳平衡点。之所以需要整合管理,是因为项目的结合部最容易出问题。
心跳包
2020/08/31
7920
【PMP】四、项目整合管理
如何做好项目管理工作?
很多项目进度很难把控,经常延期,怎么办?如何跟进整个项目的开发进度、项目测试及项目完成发布?
一个会写诗的程序员
2020/05/18
4K0
如何做好项目管理工作?
如何对进度进行有效的监控与管理?
项目进度控制是项目 管理 工作中的重要一环,但现在的软件开发项目进度失控的例子却屡见不鲜,甚至进度的延迟总是在快到计划结束的时刻暴露出来,然后谁也不知道到底什么时候才能够结束项目。因此,业内流传着这样一句令人心酸的话:“规划规划全是鬼话,计划计划全是空话”。前不久,我就遇到了这样的一个实际项目。   “当进度报告上显示已完成90%时,项目就像遇到了一个黑洞,不断地吞噬着项目组队的时间。你说这是怎么了?”在A 公司工作的一个好友和我谈起时,话语中露出了深深的不解和抱怨。是呀,问题出在哪呢?根据我的经验,这是经典的“上梁不正下梁歪”问题,我认为要想对项目进度有效的监控与管理,必须抓好以下两个方面:   ◆ 项目计划:计划的可行性和可操作性是进度监控的基础;   ◆ 项目进度度量:对项目进度进行科学的度量,才能够获得项目的真实进展情况,并对项目计划做出相应调整。   首先,我们从90%,这个项目完成百分比的来源说起,项目经理在进度报告中写下这个值的时候,他的依据是什么?在这个项目后来的实际情况来看,当时90%的数字是有误的,其实只有50%左右,说明获取这个进度数字时出现了问题。为了更好地理解这个问题,我们来看一个生活中的实际例子:   假设我们驱车从厦门开往福州,在途中我们如何获得进度信息呢?对于熟悉这一路段的司机来说这个问题很简单,可以从窗外的景象来得知已经开到哪里,从而做出正确的估计。但是对于软件开发项目而言,项目团队就像进入了一个全新的征途,就像一个第一次驶过这一路段的司机一样,很难从“窗外的景象”来判断自己的进度。那对于这样的情况,该采用什么方法呢?对于司机而言,他能够通过路边的里程碑这一个简单工具。   来获知自己的进度信息,那么为什么项目团队不为自己设立一些这样的“里程碑”呢?   从这个简单的故事中,我们似乎已经可以得到一些启示,那么现在问题的关键在于如何合理地设立标识项目进度的“里程碑”,接下来我们来看看具体如何操作。   在一个软件开发项目中,需要完成的事务很多也很复杂,其复杂度足以让任何人无法对其工作量进行有效的估计,因此对工作任务进行分解是十分重要,这也是设定里程碑的基础。但如何进行工作任务分解呢?这也许也是困扰许多人的一个问题。其实工作任务分解可以从两个方面获得帮助:   ◆ 软件开发生命周期:不管你打算采用什么样的软件开发生命周期模型,它都可以帮助你将整个软件开发项目进行阶段性的划分,而这些阶段就可以做你计划中很重要的里程碑。   ◆ 软件开发需求:软件开发生命周期只给你的项目计划提供了一个框架,而软件开发需求才是其中的血肉,因此软件开发需求的整理与规格化,是细化项目计划的基础。也就是说,在制定项目计划时,应该在你选择的软件开发生命周期模型的框架下,结合软件开发需求来细分任务和设定里程碑。   回顾在这个项目中,他们考虑到项目的复杂性,采用了其熟悉的瀑布型(软件开发生命周期),并且在制定计划时,项目经理认真参考了许多经验值,将2个月的时间按照经验值中的百分比给需求分析、系统设计、编码实现、系统测试、部署交付五个阶段分别安排了时间。并且根据软件需求说明书的内容,列出了软件模块,   并根据每个模块细化了系统设计和编码实现的进度安排。一切看起来都很正常,但是为什么还是没有效果呢?我从他们对细节的回顾中发现了一些问题:   ◆ 所有的项目计划均是由项目经理的估计值制定的,也就是说项目经理包办了整个项目计划的制定工作;   ◆ 在项目计划中只是简单地在每个阶段的结束时间上标上了一个里程碑符号;   ◆ 进度报告中的项目完成百分比,是直接通过“已经历的时间(2 个月)”计算得到的;   ◆ 项目过程中,需求在变化,但项目计划却没有跟进;   ◆ 项目延迟的主要原因在于两个方面:项目需求增加,以及系统设计和编码实现的时间都超过了原先的计划。   这一切就是典型的项目进度失控的直接诱因,相信这些项目中都能够发现以上问题的影子。那么如果避免或者解决这些问题呢?在我的资料库中,包括以下几个针对此症的“药方”,在我的实践中收到了良好效果,你也不妨试一试。 第一个药方是以面向客户的角度整理需求。我看到许多软件项目开发团队进入了系统设计和编码实现阶段之后,在整个开发团队之间的交流里充满着计算机领域的东西,却难得见到问题领域的东西,这样很容易造成软件开发与客户需求的脱节。因此,从一开始就以面向客户的角度来整理需求,让这些需求的实现成为项目团队共同的目标,这将容易使项目始终保持正确的方向。UML中的Use Case、特征驱动开发中的Feature、极限编程中的UserStory都是很好的办法,以这些方式组织的需求,作为项目计划中的血肉,将更有利于进度的安排与控制。 第二个药方是项目团队共同完成项目计划。项目计划的一个很重要的前提是项目估算,项目估算最大的基础是经验值,而软件工程书籍中的经验值反应的只
PM吃瓜
2020/07/01
2.2K0
【PMP】PMBOK第六版项目管理5大过程组10大知识领域知识点汇总
7.在没有对变更进行全面评估之前,不能找CCB,更不能立即实施变更,但是,较小的变更需不要报告给CCB.
心跳包
2020/08/31
2.2K0
【PMP】PMBOK第六版项目管理5大过程组10大知识领域知识点汇总
相关推荐
软件项目管理笔记
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 一,作用域和作用域链
    • 1.全局作用域
    • 2.函数作用域
    • 3.作用域链
      • 属性访问
  • 二.闭包
    • 1.原理
    • 2.避免闭包的方法
      • (1)立即执行函数
      • (2)使用const和let
    • 3.闭包的使用
    • 4.闭包的优缺点
      • 闭包的好处
      • 使用闭包定义对象的私有变量
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档