热门标签 | 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


推荐阅读
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
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社区 版权所有