闭包的不同形式

定义

**闭包(closure)**是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。

闭包产生的原因?

闭包的产生原因是因为在函数内部定义的函数可以访问外部函数的变量和参数,即使外部函数已经执行完毕,内部函数仍然可以访问那些变量和参数。

1、返回函数

最常用的一种形式是函数作为返回值被返回:(返回一个函数,外界保持对里的引用

var outer = function(){var b = 'local';var fn = function(){return b;}return fn;
}
console.log(outer()());

2、函数赋值

一种变形的形式是将内部函数赋值给一个外部变量:(将 outer 函数作用域里的函数 fn 赋值给全局作用域的inner,outer 执行之后,inner保持了对 outer 作用域里的引用

var inner;
var outer = function(){var name = 'Smile';var fn = function(){return name;};inner = fn ;
};
outer();
console.log(inner());

3、函数参数

闭包可以通过函数参数传递函数的形式来实现:(将F里的N作为参数给外界的Inner,F执行之后,外界Inner保持了对F里的引用

var inner = function(fn){console.log(fn());
}
var outer = function(){var name = 'Smile';var fun = function(){return name;}inner(fun);
}
outer();

4、IIFE(立即执行函数)

由前面的示例代码可知,函数F()都是在声明后立即被调用,因此可以使用IIFE来替代。但是,要注意的是,这里的Inner()只能使用函数声明语句的形式,而不能使用函数表达式。

function inner(fn){console.log(fn());
}(function(){var name= 'Smile';var fun = function(){return name;}inner(fun);
})();

5、循环赋值

在闭包问题上,最常见的一个错误就是循环赋值的错误。

function foo(){var arr = [];for(var i = 0; i < 3; i++){arr[i] = function(){return i;}}return arr;
}
var bar = foo();
console.log(bar[0]());//2 

原因:真正执行函数是bar[0](),单独拿出每个数组中第一个函数执行,外层循环已经执行完;其次方法执行产生的私有作用域,用到变量i,私有作用域里不存在 i,会根据作用域查找机制向上查询,找到的是已经是循环完毕赋值为 3 的全局变量 i

正确的写法如下

function foo(){var arr = [];for(var i = 0; i < 2; i++){arr[i] = (function fn(j){return function test(){return j;}})(i);}return arr;
}
var bar = foo();
console.log(bar[0]());//0   

5、getter & setter

我们通过提供getter()和setter()函数来将要操作的变量保存在函数内部,防止其暴露在外部

var getValue,setValue;
(function(){var num = 0;getValue = function(){return num;}setValue = function(value){if(typeof value === 'number'){num = value;}}
})();
console.log(getValue());//0
setValue(1);
console.log(getValue());//1

6、迭代器

我们经常使用闭包来实现一个累加器

var add = (function(){var count = 0;return function(){return ++count; }
})();
console.log(add())//1
console.log(add())//2  

类似地,使用闭包可以很方便的实现一个迭代器

function setup(x){var i = 0;return function(){return x[i++];}
}
var next = setup(['a','b','c']);
console.log(next());//'a'
console.log(next());//'b'
console.log(next());//'c'

总结:

无论通过何种形式,只要将内部函数传递到所在的词法作用域以外,它都会持有对原始作用域的引用,无论在何处执行这个函数都会使用闭包。

参考链接

  • https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
  • https://www.cnblogs.com/goloving/p/7775065.html
  • https://juejin.cn/post/6989817280720797710

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

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

相关文章

【Jetpack】ViewModel使用技巧

ViewModel的基本使用方法&#xff0c;这里不再讲解 ViewModel优点 可以在屏幕旋转之后&#xff0c;仍然保持之前的状态&#xff0c;这样就不用刻意去处理屏幕旋转事件可以轻松实现作用域内的单例模式可以轻松在作用域内进行数据共享 ViewMode使用注意 不能将Activity作为Co…

Centos7修改yum源

安装好系统后&#xff0c;网络能通信&#xff0c;源也没有配置&#xff0c;但是安装软件失败。 解决办法&#xff1a;配置阿里yum源 # curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # yum clean all # yum make cache再次安装软…

AI安全研究滞后?清华专家团来支招

在21世纪的科技浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;无疑是最为耀眼的一抹亮色。随着技术的不断突破&#xff0c;AI正以前所未有的速度融入我们的日常生活&#xff0c;重塑着社会、经济乃至人类文明的面貌。然而&#xff0c;在这股汹涌澎湃的发展洪流中&#…

二分查找1

1. 二分查找&#xff08;704&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 暴力解法就是遍历数组来找到相应的元素&#xff0c;使用二分查找的解法就是每次在数组中选定一个元素来将数组划分为两部分&#xff0c;然后因为数组有序&#xff0c;所以通过大小关系舍弃…

七天速通javaSE:第五天 数组基础

文章目录 前言一、认识数组二、数组的声明和创建1. 声明数组变量2. 创建数组3. 变量的初始化&#xff08;赋值&#xff09;3.1 静态初始化3.2 动态初始化 3. 示例 三、数组的使用1. 循环1.1 普通for循环1.2 For-Each 循环 2. 数组作为函数的参数和返回值 前言 本文将为大家介绍…

Win11 Python3.10 安装pytorch3d

0&#xff0c;背景 Python3.10、cuda 11.7、pytorch 2.0.1 阅读【深度学习】【三维重建】windows10环境配置PyTorch3d详细教程-CSDN博客 1&#xff0c;解决方法 本来想尝试&#xff0c;结果发现CUB安装配置对照表里没有cuda 11.7对应的版本&#xff0c;不敢轻举妄动&#x…

0051__win - RegisterWaitForSingleObject的例子

win - RegisterWaitForSingleObject的例子_registerwaitforsingleobject msdn-CSDN博客

DP:子序列问题

文章目录 什么是子序列子序列的特点举例说明常见问题 关于子序列问题的几个例题1.最长递增子序列2.摆动序列3.最长递增子序列的个数4.最长数对链5.最长定差子序列 总结 什么是子序列 在计算机科学和数学中&#xff0c;子序列&#xff08;Subsequence&#xff09;是指从一个序列…

c语言的烫烫烫烫烫??

当初学习C语言时&#xff0c;对于一些特殊的打印输出可能会感到困惑&#xff0c;比如会出现一堆乱码烫烫烫的情况。其实这是因为在C语言中&#xff0c;对于字符类型和数字类型之间的隐式转换可能会导致打印输出的结果不符合预期。这并不意味着程序员"烫"&#xff0c;…

[激光原理与应用-96]:激光器研发与生产所要的常见设备(大全)与仪器(图解)

目录 一、激光器制造设备 二、测试与校准设备 2.1 光功率计&#xff1a; 1、工作原理 2、主要功能 3、应用场景 4、测量方法 5、总结 2.2. 激光束质量分析仪&#xff1a; 1、概述 2、主要功能和特点 3、工作原理 4、常见品牌和型号 5、应用领域 6、总结 2.3 光…

力扣-2529. 正整数和负整数的最大计数

文章目录 力扣题目代码工程 力扣题目 给你一个按 非递减顺序 排列的数组 nums &#xff0c;返回正整数数目和负整数数目中的最大值。 换句话讲&#xff0c;如果 nums 中正整数的数目是 pos &#xff0c;而负整数的数目是 neg &#xff0c;返回 pos 和 neg二者中的最大值。 注…

机器人运动范围检测 c++

地上有一个m行n列的方格&#xff0c;一个机器人从坐标&#xff08;0&#xff0c;0&#xff09;的格子开始移动&#xff0c;它每次可以向上下左右移动一个格子&#xff0c;但不能进入行坐标和列坐标的位数之和大于k的格子&#xff0c;请问机器人能够到达多少个格子 #include &l…

基于大数据架构的情感分析

1 项目介绍 1.1 研究目的和意义 随着大数据时代的到来&#xff0c;电影产业积累了海量的用户评论数据&#xff0c;这些数据中蕴含着观众的情感倾向与偏好信息&#xff0c;为电影推荐和市场策略制定提供了宝贵资源。然而&#xff0c;如何高效地从这浩瀚的数据海洋中提炼出有价…

QT5:在窗口右上角显示图标

目录 一、环境与目标 二、实现逻辑&#xff08;纯代码&#xff09;与效果 三、参考代码 四、总结 一、环境与目标 qt版本&#xff1a;5.12.7 windows 11 下的 Qt Designer &#xff08;已搭建&#xff09; 目标&#xff1a;使用嵌套布局的方式将两个按钮显示在窗口右上角…

《大海》这歌为何经久不衰?你看歌词写的多美妙!

《大海》这歌为何经久不衰&#xff1f;你看歌词写的多美妙&#xff01; 《大海》是一首由陈大力作词&#xff0c;陈大力、陈秀男作曲&#xff0c;Ricky Ho编曲&#xff0c;张雨生演唱的国语流行歌曲。该曲收录在张雨生1992年11月30日由飞碟唱片发行的同名专辑《大海》中。 作为…

【JavaEE精炼宝库】多线程进阶(2)synchronized原理、JUC类——深度理解多线程编程

一、synchronized 原理 1.1 基本特点&#xff1a; 结合上面的锁策略&#xff0c;我们就可以总结出&#xff0c;synchronized 具有以下特性(只考虑 JDK 1.8)&#xff1a; 开始时是乐观锁&#xff0c;如果锁冲突频繁&#xff0c;就转换为悲观锁。 开始是轻量级锁实现&#xff…

广州外贸建站模板

Yamal外贸独立站wordpress主题 绿色的亚马尔Yamal外贸独立站wordpress模板&#xff0c;适用于外贸公司建独立站的wordpress主题。 https://www.jianzhanpress.com/?p7066 赛斯科Sesko-W外贸建站WP主题 适合机械设备生产厂家出海做外贸官网的wordpress主题&#xff0c;红橙色…

Dify自定义工具例子

1.天气&#xff08;JSON&#xff09; {"openapi": "3.1.0","info": {"title": "Get weather data","description": "Retrieves current weather data for a location.","version": "v1…

动态规划——打家劫舍(C++)

好像&#xff0c;自己读的书确实有点少了。 ——2024年7月2日 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连…

Linux 静态库和动态库

不管是Linux还是Windows中的库文件其本质和工作模式都是相同的, 只不过在不同的平台上库对应的文件格式和文件后缀不同。程序中调用的库有两种 静态库和动态库&#xff0c;不管是哪种库文件本质是还是源文件&#xff0c;只不过是二进制格式只有计算机能够识别&#xff0c;作为一…