web前端之JavaScrip中的闭包
MENU
- 闭包--笔试-11
- defineReactive函数,利用闭包封装Object.defineProperty()
- 闭包--节流函数--笔试-10
- 闭包的定义
- JavaScript闭包的9大经典使用场景
闭包–笔试-11
function fun() { var n = 9; // js 中强行给一个未声明的变量赋值,// 程序不会报错// 并且会自动在全局创建此变量add = function() { n++;}; return function() { console.log(n); };
};// 把 fun() 执行的结果赋值给 fn 变量
var fn = fun();// 此处调用的是全局的 add 函数,
// 因为全局的 add 函数作用域链引用着 fun 函数作用域对象
// 所以修改的是 fun 里面变量的值
add();
fn(); // 10// 把 fun() 执行的结果赋值给 fn2 变量
// 注意:这里的 fn2 所引用的是 fun() 执行后的地址
// 所以 fn 和 fn2 变量使用的地址是不同,结果也不相同
var fn2 = fun();
fn2(); // 9
add();
add();
fn2(); // 11
fn(); // 10
add();
fn(); // 10
defineReactive函数,利用闭包封装Object.defineProperty()
function defineReactive(data, key, val) {Object.defineProperty(data, key, {// 可枚举enumerable: true,// 可以被配置,比如可以被 deleteconfigurable: true,// getter get() { return val;},// setterset(newValue) {if (val === newValue) return false;val = newValue;}});
};
let obj = {};
defineReactive(obj, 'a', 10); // 设置 a 属性
console.log(obj.a); // 10 访问 a 的值
obj.a = 100; // 改变 a 的值
console.log(obj.a); // 100 访问改变后 a 的值
闭包–节流函数–笔试-10
1、定义
节流函数的作用是在限定的时间内函数只执行一次。
1、按钮提交(可以避免重复提交,当然不只这种方法,将按钮设置为不可用也可以)。
2、scroll、mousehover、mousemove 等触发频率高的时候。
主要的原理就是在闭包内设置一个标记,在限定的时间内这个 flag 设置为 true,函数再次点击则让执行,setTimeout 函数执行以后将 flag 设置为 flase,就可以继续执行 。
2、html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"></head><body><div class="box" id="div_box" ><button onclick="fn1()">test</button></div></body>
</html>
3、JavaScript
function throttle(fn, delay) {var flag = false;var timer = null;return function() {// 将参数转成数组var args = [].slice.call(arguments, 0); var context = this;// 如果在限定的时间内 flag 是 true 则直接返回,不让执行if(flag) return false;// 函数正在控制中flag = true; // 执行函数fn.apply(context, args);// 清除定时器clearTimeout(timer); timer = setTimeout(function() {// 延时时间过了以后,放开函数控制flag = false; }, delay); }
}function fn() {console.log(123);
}// 绑定节流函数
var fn1 = throttle(fn, 2000);
闭包的定义
定义-01
闭包是指有权访问另一个函数作用域中的变量的函数。
定义-02
闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
定义-03
闭包可以让一个函数访问并操作其声明时的作用域中的变量和函数,即使声明时的作用域消失了,也可以调用。
定义-04
闭包是一个定义在其它函数(父函数)里面的函数,它拥有对父函数里面变量的访问权。闭包有三个作用域的访问权。自身的作用域、父作用域和全局作用域。
JavaScript闭包的9大经典使用场景
1、返回值(最常用)
这个很好理解就是以闭包的形式将 name 返回。
function fn() {var name = "hello";return function (){return name;};
};
var fnc = fn();
console.log(fnc()); // hello
2、函数赋值
在闭包里面给fn函数设置值,闭包的形式把name属性记忆下来,执行会输出 hello。
var fn;
function fnc() {var name = "hello";// 将函数赋值给fnfn = function (){return name;};
};
fnc(); // 要先执行进行赋值,
console.log(fn2()); // 执行输出fn2
3、函数参数
用闭包返回一个函数,把此函数作为另一个函数的参数,在另一个函数里面执行这个函数,最终输出 hello。
function fn(){var name = "hello";return function callback() {return name;};
};
var fun = fn(); // 执行函数将返回值(callback函数)赋值给fnc
function func(f) {// 将函数作为参数传入console.log(f()); // 执行函数,并输出
};
func(fun); // 执行输出fun
4、IIFE(自执行函数)
直接在自执行函数里面将封装的函数fn1传给fn2,作为参数调用同样可以获得结果hello。
(function (){var name = "hello";var fn1 = function (){return name;};// 直接在自执行函数里面调用fn2,将fn1作为参数传入fn2(fn1);
})();
function fn2(f){// 将函数作为参数传入console.log(f()); // 执行函数,并输出
};
5、循环赋值
如果不采用闭包的话,会有不一样的情况。
// 每秒执行1次,分别输出1-10
for(var i = 1; i <= 10; i++){(function (j){// j来接收setTimeout(function (){console.log(j);}, j * 1000);})(i); // i作为实参传入
}
6、getter和setter
第一次输出 hello 用setter以后再输出 world ,这样做可以封装成公共方法,防止不想暴露的属性和函数暴露在外部。
function fn() {var name = 'hello',setName = function (n){name = n;},getName = function (){return name;};// 将setName,getName作为对象的属性返回return {setName,getName};
};
var fn1 = fn(); // 返回对象,属性setName和getName是两个函数
console.log(fn1.getName()); // getter
fn1.setName('world'); // setter修改闭包里面的name
console.log(fn1.getName()); // getter
7、迭代器(执行一次函数往下取一个值)
null
var arr = ['aa','bb','cc'];
function incre(arr) {var i = 0;return function (){// 这个函数每次被执行都返回数组arr中 i下标对应的元素return arr[i++] || '数组值已经遍历完';}
}
var next = incre(arr);
console.log(next()); // aa
console.log(next()); // bb
console.log(next()); // cc
console.log(next()); // 数组值已经遍历完
8、首次区分(相同的参数,函数不会重复执行)
null
var fn = (function (){var arr = []; // 用来缓存的数组return function (val){if(arr.indexOf(val) == -1) { // 缓存中没有则表示需要执行arr.push(val); // 将参数push到缓存数组中console.log('函数被执行了', arr);//这里写想要执行的函数} else {console.log('此次函数不需要执行');}console.log('函数调用完打印一下,方便查看已缓存的数组:', arr);};
})();
fn(10);
fn(10);
fn(1000);
fn(200);
fn(1000);
9、缓存
比如求和操作,如果没有缓存,每次调用都要重复计算,采用缓存已经执行过的去查找,查找到了就直接返回,不需要重新计算。
var fn = (function (){var cache = {}; // 缓存对象var calc = function (arr){ // 计算函数var sum = 0;// 求和for(var i = 0; i < arr.length; i++){sum += arr[i];}return sum;};return function (){var args = Array.prototype.slice.call(arguments,0); // arguments转换成数组var key = args.join(","); // 将args用逗号连接成字符串var result, tSum = cache[key];if(tSum){ // 如果缓存有 console.log('从缓存中取:', cache); // 打印方便查看result = tSum;} else {// 重新计算,并存入缓存同时赋值给resultresult = cache[key] = calc(args);console.log('存入缓存:', cache); // 打印方便查看}return result;}
})();
fn(1, 2, 3, 4, 5);
fn(1, 2, 3, 4, 5);
fn(1, 2, 3, 4, 5, 6);
fn(1, 2, 3, 4, 5, 8);
fn(1, 2, 3, 4, 5, 6);
链接
大千世界出品
相关文章:
web前端之JavaScrip中的闭包
MENU 闭包--笔试-11defineReactive函数,利用闭包封装Object.defineProperty()闭包--节流函数--笔试-10闭包的定义JavaScript闭包的9大经典使用场景 闭包–笔试-11 function fun() { var n 9; // js 中强行给一个未声明的变量赋值,// 程序不会报错// 并…...
Windows下命令行启动与关闭WebLogic的相关服务
WebLogic 的服务器类型 WebLogic提供了三种类型的服务器: 管理服务器节点服务器托管服务器 示例和关系如下图: 对应三类服务器, 就有三种启动和关闭的方式。本篇介绍使用命令行脚本的方式启动和关闭这三种类型的服务器。 关于WebLogic 的…...
LeetCode Hot100 169.多数元素
题目: 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 方法一:哈希表 class Solution {public int…...
数据结构:堆的实现思路
我们之前写过堆的实现代码:数据结构:堆的实现-CSDN博客 这篇文章我们了解一下堆到底是如何实现的 1.堆向下调整算法 现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆 向下调…...
结合 DBSCAN 示例代码介绍 DBSCAN
前文为JoyT的科研之旅第一周——科研工具学习及论文阅读收获-CSDN博客 DBSCAN 介绍 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它能够识别出任意形状的簇,并有效地处理噪声…...
vscode 调试jlink
文章目录 软件使用说明1、启动GDB Server2、下载gdb3、vscode配置4、调试 软件 vscodejlink - (JLinkGDBServer.exe)gcc-arm-none-eabi-10-2020-q4-major (arm-none-eabi-gdb.exe) 使用说明 vscode通过TCP端口调用JLinkGDBServer通过jlink连接和操作设备,vscode不…...
微前端实战:打造高效、灵活的前端应用架构
文章目录 一、微前端简介二、微前端的优势1. 高度模块化2. 独立部署3. 易于扩展4. 技术栈无关5. 独立升级 三、微前端的原理四、微前端案例思路《微前端实战》编辑推荐内容简介作者简介目录前言/序言 随着互联网行业的快速发展,前端应用的规模和复杂度也在不断增加。…...
csv文件EXCEL默认打开乱码问题
这里讨论的问题是,当用记事本打开带有中文字符的csv正常时,用excel打开却是乱码。 简单概括就是:编码问题,windows的 excel打开csv文本文件时,默认使用的是系统内的ANSI,在中文环境下就是GB2312。如果写文件…...
C语言之实现贪吃蛇小游戏篇(2)
目录 🎇测试游戏test.c 🎇游戏头文件包含&函数声明snake.h 🎇游戏实现snake.c 🎇测试游戏test.c #define _CRT_SECURE_NO_WARNINGS 1 #include "snake.h" void test() {int ch 0;do{Snake snake { 0 };//创建…...
Comparator接口
Comparator接口 Comparator 是 Java 中用于比较对象的接口。它允许开发者实现自定义的比较逻辑,以用于对对象进行排序或者确定它们的顺序。 主要方法: Comparator 接口中包含一个抽象方法: int compare(T o1, T o2):用于比较两…...
SELinux refpolicy详解(9)
接前一篇文章:SELinux refpolicy详解(8) 三、refpolicy内容详解 上一回讲解了refpolicy源码根目录下的build.conf文件的前一部分内容。本回继续讲解其后一部分。 2. build.conf 文件路径:refpolicy源码根目录/build.conf。 文…...
零基础上手,秒识别检测,IDEA研究院发布全新T-Rex模型
目标检测作为当前计算机视觉落地的热点技术之一,已被广泛应用于自动驾驶、智慧园区、工业检测和卫星遥感等场景。开发者在研究相关目标检测技术时,通常需熟练掌握图像目标检测框架,如通用目标检测框架 YOLO 系列,旋转目标检测框架…...
python每日一题——20旋转图像
题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]]…...
云计算生成式 -给你不一样的音乐推荐新体验
目录 摘要: 正文: 一、亚马逊云与生成式 AI 结合的展望/总结 二、我用亚马逊云科技生成式 AI 产品打造了什么,解决了什么问题 三、未来云端技术发展趋势的见解 四、云端技术未来需要解决的问题 1、如何保护数据安全和隐私? …...
Zabbix 6.0部署+自定义监控项+自动发现与自动注册+部署zabbix代理服务器
Zabbix 6.0 Zabbix 6.0一、关于zabbix1、什么是zabbix2、zabbix工作原理3、zabbix 6.0 特性4、zabbix 6.0 功能组件 二、Zabbix 6.0 部署1、 部署 zabbix 服务端(1) 部署 Nginx PHP 环境并测试(2) 部署数据库(3) 编译安装 zabbix server 服务端(4) 部署 Web 前端,进…...
Docker 简介及其常用命令详解
Docker 简介及其常用命令详解 Docker 自推出以来,已成为开发和运维领域的重要工具。它简化了应用的部署、测试和分发过程,使得容器化技术成为现代软件开发的标准实践。本文将为您提供Docker的基础介绍以及其常用命令的详细讲解。 什么是Docker…...
基于PHP的高中生物学习平台
有需要请加文章底部Q哦 可远程调试 基于PHP的高中生物学习平台 一 介绍 此高中生物学习平台基于原生PHP开发,数据库mysql。系统角色分为用户和管理员。(附带参考设计文档) 技术栈:phpmysqlphpstudyvscode 二 功能 学生 1 注册/登录/注销 2 个人中心 …...
Git多库多账号本地SSH连接配置方法
Git多库多账号本地SSH连接配置方法 一、前言二、环境三、帮助文档四、多环境配置4.1 配置config文件 五、生成RSA秘钥对5.1 ssh秘钥位置5.2 生成秘钥对(公钥、私钥)5.3 添加公钥到GIT用户配置中 六 测试git是否可以使用七、总结 一、前言 在使用Git管理…...
爬虫学习-基础(HTTP原理)
目录 一、URL和URI 二、HTTP和HTTPS (1)HTTP (2)HTTPS (3)HTTP与HTTPS区别 (4)HTTPS对HTTP的改进:双问的身份认证 三、TCP协议 (1)TCP三次握手…...
Gazebo 中为地面和车轮添加摩擦属性
Gazebo 中为地面和车轮添加摩擦属性 Link friction properties not applied from URDF to Gazebo SDFormat Specification Adding friction to model wheels Gazebo中模型自行滑动(后溜)的原因探究 移动机器人在仿真时,一旦以较大的速度启动&…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
