这篇文章主要介绍了JavaScript闭包实例代码分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript闭包实例代码分析文章都会有所收获,下面我们一起来看看吧。 闭包的概念是有很多版本,不同的地方对闭包的说法不一维基百科:在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是在支持头等函数的编程语言中实现词法绑定的一种技术。MDN: 闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。个人理解:闭包是一个函数(返回一个函数)返回的函数保存了对外变量引用
functionfn(){letnum=1;returnfunction(n){returnn+num } }letrFn=fn()letnewN=rFn(3)//4
num 变量作用域在 fn 函数中, rFn 函数却能访问 num 变量,这就是闭包函数能访问外部函数变量。浏览器VS Code 配合 Node.js看到 Closure 中 fn 是闭包函数,其中保存 num 变量。
for(vari=1;i{console.log(i); },i*1000); }
输出的结果都是 6,为什么?for 循环是同步任务setTimeout 异步任务for 循环一次,就会将 setTimeout 异步任务加入到浏览器的异步任务队列中,同步任务完成之后,再从异步任务中拿新任务在线程中执行。由于 setTimeout 能够访问外部变量 i, 当同步任务完成之后,i 已经变成了6, setTimeout 中能够访问变量 i 都是 6。
for(vari=1;i{console.log(i); },i*1000); }
for(vari=1;i{console.log(i); },i*1000) })(i) }
第三个参数意思:附加参数,一旦定时器到期,它们会作为参数传递给要执行的函数
for(vari=1;i{console.log(j); },1000*i,i); }
functionadd(num){returnfunction(y){returnnum+y; }; };letincOneFn=add(1);letn=incOneFn(1);//2letdecOn免费云主机、域名eFn=add(-1);letm=decOneFn(1);//0
add 函数的参数
保存了闭包函数变量。在函数式编程闭包有非常重要的作用,lodash 等早期工具函数弥补 javascript 缺陷的工具函数,有大量的闭包的使用场景。创建私有变量延长变量生命周期防止滚动行为,过度执行函数,必须要节流, 节流函数接受 函数
+ 时间
作为参数,都是闭包中变量,以下是一个简单 setTimeout 版本:
functionthrottle(fn,time=300){vart=null;returnfunction(){if(t)return; t=setTimeout(()=>{ fn.call(this); t=null; },time); } }
一个简单的基于 setTimeout 防抖的函数的实现
functiondebounce(fn,wait){vartimer=null;returnfunction(){if(timer!==null){clearTimeout(timer); } timer=setTimeout(fn,wait); } }
问题说明:父/子
组件关系, 父子组件都能使用 click 事件同时修改 state 数据, 并且子组件拿到传递下的 props 事件属性,是经过 useCallback
优化过的。也就是这个被优化过的函数,存在闭包陷阱,(保存一直是初始 state 值)
import{useState,useCallback,memo}from"react";constChildWithMemo=memo((props:any)=>{return(); });constParent=()=>{const[count,setCount]=useState(1);consthandleClickWithUseCallback=useCallback(()=>{console.log(count); },[]);//注意这里是不能监听count,因为每次变化都会重新绑定,造成造成子组件重新渲染 return(); };exportdefaultParentparentcount:{count}
ChildWithMemo 使用 memo 进行优化,handleClickWithUseCallback 使用 useCallback 优化问题是点击子组件时候,输出的 count 是初始值(被闭包了)。解决办法就是使用 useRef 保存操作变量函数:
import{useState,useCallback,memo,useRef}from"react";constChildWithMemo=memo((props:any)=>{console.log("renderedchildren")return(); });constParent=()=>{const[count,setCount]=useState(1);constcountRef=useRef(null) countRef.current=()=>{console.log(count); }return(); };exportdefaultParentparentcount:{count}
针对这个问题,React 曾经认可过社区提出的增加 useEvent 方案,但是后面 useEvent 语义问题被废弃了,对于渲染优化 React 采用了编译优化的方案。其实类似的问题也会发生在 useEffect 中,使用时要注意闭包陷阱。闭包不要随意定义,定义了一定找到合适的位置进行销毁。因为闭包的变量保存在内存中,不会被销毁,占用较高的内存。打开开发者工具,选择 Timeline 面板在顶部的Capture
字段里面勾选 Memory点击左上角的录制按钮。在页面上进行各种操作,模拟用户的使用情况。一段时间后,点击对话框的 stop 按钮,面板上就会显示这段时间的内存占用情况。关于“JavaScript闭包实例代码分析”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“JavaScript闭包实例代码分析”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注云技术行业资讯频道。
今天小编给大家分享一下怎么使用Node实现轻量化进程池和线程池的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、名词定义学术上说,进程是一个具有…