闭包的理解?闭包使用场景

说说你对闭包的理解?闭包使用场景

#一、是什么

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)

也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域

在 JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁

下面给出一个简单的例子

function init() {
    var name = "Mozilla"; // name 是一个被 init 创建的局部变量
    function displayName() { // displayName() 是内部函数,一个闭包
        alert(name); // 使用了父函数中声明的变量
    }
    displayName();
}
init();

displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量

#二、使用场景

任何闭包的使用场景都离不开这两点:

  • 创建私有变量
  • 延长变量的生命周期

一般函数的词法环境在函数返回后就被销毁,但是闭包会保存对创建时所在词法环境的引用,即便创建时所在的执行上下文被销毁,但创建时所在词法环境依然存在,以达到延长变量的生命周期的目的

下面举个例子:

在页面上添加一些可以调整字号的按钮

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

#柯里化函数

柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用

// 假设我们有一个求长方形面积的函数
function getArea(width, height) {
    return width * height
}
// 如果我们碰到的长方形的宽老是10
const area1 = getArea(10, 20)
const area2 = getArea(10, 30)
const area3 = getArea(10, 40)

// 我们可以使用闭包柯里化这个计算面积的函数
function getArea(width) {
    return height => {
        return width * height
    }
}

const getTenWidthArea = getArea(10)
// 之后碰到宽度为10的长方形就可以这样计算面积
const area1 = getTenWidthArea(20)

// 而且如果遇到宽度偶尔变化也可以轻松复用
const getTwentyWidthArea = getArea(20)

#使用闭包模拟私有方法

JavaScript中,没有支持声明私有变量,但我们可以使用闭包来模拟私有方法

下面举个例子:

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }
})();

var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */

上述通过使用闭包来定义公共函数,并令其可以访问私有函数和变量,这种方式也叫模块方式

两个计数器 Counter1 和 Counter2 是维护它们各自的独立性的,每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境,不会影响另一个闭包中的变量

#其他

例如计数器、延迟调用、回调等闭包的应用,其核心思想还是创建私有变量和延长变量的生命周期

#三、注意事项

如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。

原因在于每个对象的创建,方法都会被重新赋值

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

上面的代码中,我们并没有利用到闭包的好处,因此可以避免使用闭包。修改成如下:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg和Monibuka拉取rtsp(大华摄像头)视频流时未进行URLCode编码导致提示404等报错

场景 Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放: Monibucav4(开源流媒体服务器)在Windows上搭建rtmp服务器并实现拉取rtsp视频流以及转换flv播放_monibuca 搭建流媒体服务-CSDN博客 Nginx搭建RTMP服务器FFmpeg…

Origin 2022下载安装教程,操作简单,小白也能轻松搞定,附安装包,带软件使用教程

前言 Origin是一个科学绘图、数据分析软件,支持各种各样的2D/3D图形,包括统计,信号处理,曲线拟合以及峰值分析,Origin具有强大的数据导入功能和多样的图形输出格式。 准备工作 1、Win7及以上系统 2、提前准备好 Or…

十分钟快速上手Spring Boot与微信小程序API接口的调用,快速开发小程序后端服务

1.1 微信小程序API接口介绍 微信小程序API接口是连接小程序前端与后端服务器的桥梁,它提供了丰富的功能接口,包括用户信息、支付、模板消息、数据存储等。这些API接口能够满足开发者在小程序中实现各种复杂业务逻辑的需求。 用户信息接口 用户信息接口…

Windows PC版微信内置浏览器调试(更新版)

前言 在日常的开发中,尤其是在微信公众号的相关开发中,我们需要进行微信端的调试,如果是后端开发,频率会更高。早期的微信版本,还支持查看网页元素以及接口请求,近年来,微信将这个功能频闭掉了…

链动2+1:打造企业级社交电商新篇章

随着互联网的迅猛发展,社交电商已成为商业领域的新宠。而在众多社交电商模式中,链动21模式以其独特的优势和魅力,正逐渐成为企业级用户的首选。本文将深入探讨链动21模式的优势,以及如何助力企业级用户实现商业成功。 一、链动21模…

vue环境安装 nodejs和vue

npm 是 NodeJS 下的包管理器,vue-cli脚手架模板就是基于 node 下的 npm 来完成安装的。 webpack: 它的主要用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资源的合并和打包。 vue-cli:官方提供的一个脚手架,用于快速生成一个 vue 的项目模板。…

精通Python第16篇—深入解析Pyecharts极坐标系参数与实战

文章目录 Pyecharts绘制多种炫酷极坐标系参数说明与方向的技术博客1. 导入必要的库2. 极坐标系基础3. 定制化极坐标系4. 方向性的极坐标系5. 极坐标系的动画效果6. 自定义极坐标轴标签7. 添加极坐标系的背景图8. 极坐标系的雷达图总结 Pyecharts绘制多种炫酷极坐标系参数说明与…

Unity触发检测Trigger踩坑合集

正常状态 绿色方块:刚体碰撞盒检测触发碰撞脚本 蓝色方块:碰撞盒 检测脚本: 正常进出: 踩坑1 绿色方块:刚体碰撞盒检测触发碰撞脚本 蓝色方块:碰撞盒 保持绿色和蓝色方块的接触 对蓝色方块&#xff1a…

http代理与socks5代理有什么差异,http代理出现502错误如何修复?

一、HTTP代理与SOCKS5代理的差异HTTP代理和SOCKS5代理都是网络代理服务的两种主要类型,但它们在实现方式和应用场景上存在明显的差异。1.协议差异HTTP代理基于HTTP协议,是一种应用层代理,主要用于代理HTTP请求和响应。而SOCKS5代理则基于SOCK…

幻兽帕鲁服务器一键部署保姆教程

在帕鲁的世界,你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活,也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活,也可以为你在工厂工作。你也可以将它们进行售卖,或肢解后食用。 想要部署属于自…

BC1.2 SDP/CDP/DCP介绍

参考:文章链接 Microchip Lightning Support 问题 Q1.) 在Microchip产品的数据表中提到了电池充电技术,但以下术语是什么意思: BC1.2? SDP? CDP? DCP? “SE1”? Q2.) 如何配置Microchip Hub以启用这些功能? Q3.) 如何在我的硬件上物…

Codeforces Round 922 (Div. 2)补题

Brick Wall(Problem - A - Codeforces) 题目大意:规定砖的大小为1*k(k>2),现在有一面n*m的砖墙,n是墙高,m是墙宽,砖在砖墙中有两种放法,水平放置和竖直放置&#xff…

修复WordPress内部服务器错误的步骤及解决方案

WordPress是一款广泛使用的开源内容管理系统,但在使用过程中,可能会遇到各种内部服务器错误。这些错误可能由于多种原因引起,例如插件冲突、文件权限问题、服务器配置不当等。为了帮助您快速解决这些问题,本文将为您提供一套详细的…

智能优化算法 | Matlab实现霸王龙优化算法(TROA)(内含完整源码)

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 智能优化算法 | Matlab实现霸王龙优化算法(TROA)(内含完整源码) 源码设计 %%clear all clcSearchAgents_no=50; % Number of search agentsFunction_name=</

Spring AOP原理的常见面试题

Spring AOP原理的常见面试题 .Spring AOP是怎么实现的什么是代理模式静态代理动态代理怎么实现的JDK动态代理CGLIB动态代理引入依赖 JDK与CJLIB的区别什么时候使用JDK与CJLIB . Spring AOP是怎么实现的 答:Spring AOP是通过动态代理来实现AOP的 什么是代理模式 答:代理模式也…

离线使用Element UI和Vue

需要依赖如下&#xff1a; 1.vue.js; 2.index.js(Element UI) 3.index.css(Element UI) 4.element-icons.ttf(Element UI字体) 5.element-icons.woff(Element UI图标) 下载链接如下&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1nGOi0Vm_xExRGmVp6oVLoA 提取…

Django问题报错:Cannot resolve keyword ‘name‘ into field. Choices are: course, id

笔者在进行登录注册实验用户名已经注册过的操作时报错 一、错误位置 二、问题原因 使用Student模型时参数名错误 三、解决办法 修改为与Student模型中对应的参数名,问题解决

Cache Lab:Part A【模拟出使用LRU策略的高速缓存存储器组织结构】

目录 任务描述 知识回顾 实验内容 测试结果 Cache Lab 对应《CS:APP》6.3节至第六章结束的内容。 任务描述 Your job for Part A is to fill in the csim.c file so that it takes the same command line arguments and produces the identical output as the reference …

0131-2-关于事件捕获和冒泡

关于事件捕获和冒泡 DOM事件流分为三个阶段&#xff1a;捕获阶段、目标阶段、冒泡阶段 点击目标元素后&#xff0c;不会马上触发目标元素&#xff0c;而是先执行事件捕获&#xff0c;从顶部逐步到目标元素&#xff1b;处于目标阶段的时候触发目标元素&#xff1b;最后冒泡阶段…

性能测试工具架构

背景 性能测试工具&#xff08;LoadRunner为例&#xff09; 性能测试工具通常是指那些用来支持压力、负载测试&#xff0c;能够录制和生成脚本、设置和部署场景、产生并发用户和向系统施加持续压力的工具。 性能测试工具录制的是服务端与应用之间的通信数据&#xff0c;而不是…