热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JS进修笔记——闭包的运转机制和作用域

本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。

1. 什么是闭包

MDN定义:Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions ‘remember’ the environment in which they were created.

You Don’t Know JS: Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.

我所明白的闭包就是,纵然外部函数已运转终了,内部函数仍能接见外部函数的作用域中的变量。
抓重点: 函数, 作用域。

2. 闭包的运转机制

2.1 词法作用域查找划定规矩

在闭包的运用中,为何我们可以经由过程闭包接见外部函数的作用域中的变量?其一,词法作用域的查找划定规矩是“冒泡”的,即向外层一层层查找,直到全局作用域,所以可以接见外部函数的作用域。其二,函数的作用域是定义时地点的作用域,而不是运转时的作用域。

function foo() {
var a = 1;
function bar() {
console.log(a);
}
return bar;
}
var a = 2;
var baz = foo();
baz(); //1

在上面的代码中,因为bar定义在foo的内部,因而可以向外“冒泡”接见foo的作用域。当运转baz时,a的值为1而不是2,也说清楚明了函数的作用域是定义时的作用域,是静态的。

2.2 渣滓接纳 + 援用

当函数实行终了后,引擎的渣滓接纳机制会开释不再运用的内存空间。因而,当外部函数实行终了时,外部函数的内部作用域理应是该被烧毁的。但是,因为闭包存在对外部函数作用域的援用,因而此作用域依然存在,所以内部函数仍能在外部函数实行完毕以后接见外部函数定义的变量,此之为“记着”

3. 闭包的运用场景

3.1 私有变量 + 模块

需求:只能经由过程函数供应的要领接见函数内部的变量——隐蔽。只能内部接见——私有。

function bookInfo() {
var book = {
name: "You Don't know JS",
price: 66
};

function getPrice() {
console.log(book.price);
}; function getName() {
console.log(book.name);
}; function setPrice(price) {
book.price = price;
}; return {
getPrice,
getName,
setPrice
};
};
var book = bookInfo();
book.getPrice(); //66
book.getName(); //"You Don't know JS"
book.setPrice(100);
book.getPrice(); //100

在以上的代码中,bookInfo经由过程返回一个对象,该对象的值是对内部函数的援用,而不是对变量的援用。因而,完成了函数内部变量是隐蔽的(只能经由过程返回的对象要领接见)且私有的(只要函数内部才接见)。

在模块中,返回的变量就被称为模块的大众API,模块内部的变量只能经由过程这些要领去运用。

3.2 偏函数运用

需求:函数须要先接收一些参数,随后再接收另一些参数的时刻。
比方,当我盘算商品的总价钱时,我想先设定商品的单价,随后依据购置数目算出总的商品价钱。

function partialApply(fn, ...fixedArgs) {
return function (...remainingArgs) {
return fn.apply(this, fixedArgs.concat(remainingArgs));
}
}
function calTotalPrices(price, count) {
console.log(price * count);
}
var pay = partialApply(calPrice, 10);
pay(5);

在上面的代码中,pay就是在partialApply的外部接见了partialApply的内部变量(函数参数)。

4. 为何闭包很主要?参考资料
  • 制服 Javascript 口试:什么是闭包?| Eric Elliott

  • You Don’t know Javascript


推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
author-avatar
灰包蛋啦_199
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有