成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

簡單了解JavaScript閉包

本篇文章給大家帶來了關于JavaScript的相關知識,其中主要介紹了關于JavaScript閉包的相關問題,閉包的概念有很多版本,不同的地方對閉包的說法不一,下面一起來看一下,希望對大家有幫助。

簡單了解JavaScript閉包

什么是閉包?

閉包的概念是有很多版本,不同的地方對閉包的說法不一

維基百科:在計算機科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數閉包(function closures),是在支持頭等函數的編程語言中實現詞法綁定的一種技術。

MDN: 閉包(closure)是一個函數以及其捆綁的周邊環境狀態(lexical environment詞法環境)的引用的組合。

個人理解:

  • 閉包是一個函數(返回一個函數)
  • 返回的函數保存了對外變量引用

一個簡單的示例

function fn() {    let num = 1;    return function (n) {        return n + num     } }let rFn = fn()let newN = rFn(3) // 4
登錄后復制

num 變量作用域在 fn 函數中, rFn 函數卻能訪問 num 變量,這就是閉包函數能訪問外部函數變量。

從瀏覽器調試和 VSCode Nodejs 調試看閉包

  • 瀏覽器

簡單了解JavaScript閉包

  • VS Code 配合 Node.js

簡單了解JavaScript閉包

看到 Closure 中 fn 是閉包函數,其中保存 num 變量。

一個經典的閉包:單線程事件機制+循環問題,以及解決辦法

for (var i = 1; i <= 5; i++) {  setTimeout(() => {    console.log(i);   }, i * 1000); }
登錄后復制

登錄后復制

輸出的結果都是 6,為什么?

  • for 循環是同步任務
  • setTimeout 異步任務

for 循環一次,就會將 setTimeout 異步任務加入到瀏覽器的異步任務隊列中,同步任務完成之后,再從異步任務中拿新任務在線程中執行。由于 setTimeout 能夠訪問外部變量 i, 當同步任務完成之后,i 已經變成了6, setTimeout 中能夠訪問變量 i 都是 6。

解決辦法1:使用 let 聲明

for (var i = 1; i <= 5; i++) {  setTimeout(() => {    console.log(i);   }, i * 1000); }
登錄后復制

登錄后復制

解決辦法2:自執行函數 + 閉包

for (var i = 1; i <= 5; i++) {   (function(i){      setTimeout(() => {    console.log(i);   }, i * 1000)   })(i) }
登錄后復制

解決辦法3:setTimeout 傳遞第三參數

第三個參數意思:附加參數,一旦定時器到期,它們會作為參數傳遞給要執行的函數

for (var i = 1; i <= 5; i++) {  setTimeout((j) => {    console.log(j);   }, 1000 * i, i); }
登錄后復制

閉包與函數科里化

function add(num) {  return function (y) {    return num + y;   }; };let incOneFn = add(1); let n = incOneFn(1);  // 2let decOneFn = add(-1); let m = decOneFn(1); // 0
登錄后復制

add 函數的參數保存了閉包函數變量。

實際作用

在函數式編程閉包有非常重要的作用,lodash 等早期工具函數彌補 javascript 缺陷的工具函數,有大量的閉包的使用場景。

使用場景

  • 創建私有變量
  • 延長變量生命周期

節流函數

防止滾動行為,過度執行函數,必須要節流, 節流函數接受 函數 + 時間作為參數,都是閉包中變量,以下是一個簡單 setTimeout 版本:

function throttle(fn, time=300){    var t = null;    return function(){        if(t) return;         t = setTimeout(() => {             fn.call(this);             t = null;         }, time);     } }
登錄后復制

防抖函數

一個簡單的基于 setTimeout 防抖的函數的實現

function debounce(fn,wait){    var timer = null;    return function(){        if(timer !== null){            clearTimeout(timer);         }         timer = setTimeout(fn,wait);     } }
登錄后復制

React.useCallback 閉包陷阱問題

問題說明:父/子 組件關系, 父子組件都能使用 click 事件同時修改 state 數據, 并且子組件拿到傳遞下的 props 事件屬性,是經過 useCallback 優化過的。也就是這個被優化過的函數,存在閉包陷阱,(保存一直是初始 state 值)

import { useState, useCallback, memo } from "react";const ChildWithMemo = memo((props: any) => {  return (    <div>       <button onClick={props.handleClick}>Child click</button>     </div>   ); });const Parent = () => {  const [count, setCount] = useState(1);  const handleClickWithUseCallback = useCallback(() => {    console.log(count);   }, []); // 注意這里是不能監聽 count, 因為每次變化都會重新綁定,造成造成子組件重新渲染    return (    <div>       <div>parent count : {count}</div>       <button onClick={() => setCount(count + 1)}>click</button>       <ChildWithMemo handleClick={handleClickWithUseCallback} />     </div>   ); };export default Parent
登錄后復制

  • ChildWithMemo 使用 memo 進行優化,
  • handleClickWithUseCallback 使用 useCallback 優化

問題是點擊子組件時候,輸出的 count 是初始值(被閉包了)。

解決辦法就是使用 useRef 保存操作變量函數:

import { useState, useCallback, memo, useRef } from "react";const ChildWithMemo = memo((props: any) => {  console.log("rendered children")  return (    <div>       <button onClick={() => props.countRef.current()}>Child click</button>     </div>   ); });const Parent = () => {  const [count, setCount] = useState(1);  const countRef = useRef<any>(null)    countRef.current = () => {    console.log(count);   }  return (    <div>       <div>parent count : {count}</div>       <button onClick={() => setCount(count + 1)}>click</button>       <ChildWithMemo countRef={countRef} />     </div>   ); };export default Parent
登錄后復制

針對這個問題,React 曾經認可過社區提出的增加 useEvent 方案,但是后面 useEvent 語義問題被廢棄了,對于渲染優化 React 采用了編譯優化的方案。其實類似的問題也會發生在 useEffect 中,使用時要注意閉包陷阱。

性能問題

  • 閉包不要隨意定義,定義了一定找到合適的位置進行銷毀。因為閉包的變量保存在內存中,不會被銷毀,占用較高的內存。

使用 chrome 面板功能 timeline + profiles 面板

  1. 打開開發者工具,選擇 Timeline 面板
  2. 在頂部的Capture字段里面勾選 Memory
  3. 點擊左上角的錄制按鈕。
  4. 在頁面上進行各種操作,模擬用戶的使用情況。
  5. 一段時間后,點擊對話框的 stop 按鈕,面板上就會顯示這段時間的內存占用情況。

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
亚洲产在线精品亚洲第一站一| 无码人妻丰满熟妇奶水区毛片| 人妻少妇无码精品专区| 日韩精品东京热无码视频| 斯诺克直播在线观看高清直播| 无线乱码A区B区C区D| 亚洲AV永久无码精品九之| 亚洲欲色欲WWW怡红院| 51CG9热心的朝阳群众| 被黑人猛男连续高潮视频| 国产AV无码一区二区二三区J| 国产亚洲日韩欧美另类丝瓜APP| 娇小XXXXBXBⅨ中国XX| 美女扒开粉嫩尿口的照片| 欧美最猛黑人XXXX黑人猛交9 | 狠狠色婷婷久久综合频道毛片| 久久久久久精品免费免费麻辣| 男朋友想吻我腿中间那个部位| 日本伊人精品一区二区三区 | 国产精品白丝AV嫩草影院| 狠狠色婷婷久久一区二区| 免费人成在线观看网站品善网| 日本丰满妇人成熟免费中文字幕 | 一本之道加勒比在线观看| 锕锕锕锕锕锕锕好疼免费看网站 | 久久精品熟女亚洲AV艳妇| 女生裙子里面到底穿了啥| 糖心短视频VLOG柚子猫| 亚洲人成网亚洲欧洲无码久久| 9999国产精品欧美久久久久久| 动漫AV纯肉无码AV在线播放| 精品久久人妻AV中文字幕| 欧美成年黄网站色视频| 无码人妻精品一区二区蜜桃百度| 亚洲性无码AV在线DVD| HEYZO高清中文字幕在线| 国产乱人伦偷精品视频免下载| 久久精品熟女亚洲AV艳妇| 日产精品久久久久久久性色| 亚洲AV无码潮喷在线入口| 92国产精品午夜福利免费| 国产精品天干天干| 久久无码中文字幕免费影院蜜桃| 日韩精品无码AV中文无码版| 亚洲人成人网站色www小说| 成 年 人 黄 色 大 片大 全| 精品国产AⅤ无码一区二区| 人妻免费久久久久久久了| 亚洲国产AV一区二区三区四区| SEERX性欧美| 精品国产18久久久久久| 日本少妇人妻XXXXX18免费| 亚洲日韩AV无码一区二区三区人| 成人用品有限公司| 久久久久久久女国产乱让韩| 少妇性饥渴VIDEOS| 中国熟妇人妻性XXXXX在线看| 国产精品久久久久久久久免费蜜桃 | 内射口爆少妇麻豆| 亚洲AV永久无码成人红楼影视| 凹凸视频免费在线| 久久国产欧美成人网站| 天美传媒国色天香乱码| 696969大但人文艺术来源| 国产小受呻吟GV视频在线观看| 欧洲精品一线二线三线区别| 亚洲国产AⅤ精品一区二区百度| 草莓视频在线观看18| 久久久无码精品亚洲日韩蜜臀浪潮 | 久久久久久久精品无码Av少妇| 同性男男黄H片在线播放网站| 坐公交车居然被弄了2个小时| 国产中年熟女高潮大集合| 日韩乱码人妻无码中文字幕视频| 一区二区操逼视频| 国产精品无码AV不卡| 人妻少妇精品视频一区二区三区 | 宝贝腿开大点我添添公视频免费| 久久精品国产亚洲AV高清热| 无码人妻出轨与黑人中文字幕| 啊灬啊灬啊灬快灬高潮了听书 | 中文字幕人乱码中文字幕| 国内自拍视频一区二区三区| 少妇 黑人 欧美 亚洲| 99国产精品无码专区| 九九国产精品无码免费视频| 无码专区一VA亚洲V天堂| 白人极品少妇XXXⅩ做受| 老阿姨哔哩哔哩B站肉片茄子芒果| 亚洲AⅤ成人精品无码| 福利 无码 三级 视频| 欧洲PAYPAL网站WWW| 中文天堂在线WWW最新版官网| 精品人妻一区二区三区| 性CHINESE新婚VIDEO| 大又大粗又爽又黄少妇毛片免费 | 久久精品国产亚洲AV成人| 亚洲AV无码乱码精品观看| 国产成年无码久久久久下载| 日本精品一线二线三线区别在哪里| 中文字幕无码成人免费视频| 久久精品亚洲熟妇少妇任你躁 | AV免费网址在线观看| 老公朋友东西好大| 亚洲色精品AⅤ一区区三区| 国产专区国产AV| 无码中文AV波多野吉衣迅雷下载| 抽搐一进一出再深一点| 人妻欲求不满中文字幕在线| 99久久久精品免费观看国产| 免费观看黄A级毛片| 曰本熟妇色XXXXX曰本妇| 久久精品人妻系列无码专区| 亚洲日韩乱码中文无码蜜桃臀| 好黄好污美女裸体网站| 亚洲AV成人片色在线观看蜜臀| 国产精品VA无码免费| 透过校服的乳尖 揉捏| 夫妇当面交换作爱2| 色欲AV久久一区二区三区久| 成人亚洲色欲色一欲WWW| 日本人做暖免费高清视频| 爱丫爱丫影院在线视频| 人妻精品久久一区二区av| 边做边爱边吃奶叫床的动态图| 人妻去按摩店被黑人按中出| 锕锕锕锕锕~好深啊免费软件| 欧洲人妻丰满AV无码久久不卡| JAPANESE极品丰满少妇| 青草青草久热精品视频国产4| JIZZ中国JIZZ在线观看| 欧美亚洲精品SUV| 草棚CAOPORON已满18进| 日韩AV无码午夜免费福利制服 | 日韩欧美亚洲综合久久影院DS| 成人免费看的A级毛片| 少妇久久久久久被弄高潮| 国产成人精品A视频免费福利| 天天天天做夜夜夜夜做无码| 国产经典一区二区三区蜜芽| 性BBBBBB裸体BBBBB开| 精品国产福利在线观看| 野花视频在线观看| 美丽人妻被按摩中出中文字幕| 91久久精品www人人做人人爽| 欧美最猛黑人AAAAAXXX片| 草草浮力院禁止18进入| 少妇寂寞难耐被黑人中出| 国产精品亚洲一区二区无码| 亚洲AV无码久久| 久久AV无码AV高潮AV| 中文字幕V亚洲ⅤV天堂| 欧美日韩亚洲中文字幕二区| 成年午夜无码AV片在线观看| 无码精品H动漫成人影院| 国内精品久久影院综合日日| 亚洲夜夜性无码国产盗摄| 男人边吃奶边做呻吟免费视频 | 人人澡人人妻人人爽人人蜜桃| 夫妻之间的100种插秧法| 亚洲AV色香蕉一区二区三区蜜桃| 久久国产色AV免费看| 99精品国产在热久久婷婷| 三个男人躁我一个爽视频免费| 国产精品亚洲产品一区二区三区 | WWW免费视频在线观看播放| 色天使色偷偷色噜噜噜AV天堂| 国产女人的高潮国语对白| 亚洲人成色777777精品百度| 嫩BBB槡BBBB搡BBBB| 东京热无码人妻精品一区二区三区| 性欧美VIDEO高清| 久久亚洲精品AB无码播放| 把腿张开老子臊烂你的动漫| 午夜.DJ高清免费观看视频| 久久精品成人免费国产片| av在线一区二区三区| 偷玩朋友熟睡人妻| 久久久久久久久久久精品尤物| JIZZJIZZ日本护士水好多| 无码精品人妻一区二区三区aV | 国产精品高清一区二区三区人妖| 亚洲欧洲中文日韩乱码AV | 天堂√中文在线BT| 久久不见久久见中文字幕免费| CEKC老妇女CEA0| 亚洲AⅤ在线无码播放毛片一线天| 美女扒开腿让男人桶爽直播| 公咬着小娇乳H边走边欢视频| 亚洲男人综合久久综合天堂| 青青青国产手线观看视频2019| 国产老妇伦国产熟女老妇久 | 亚洲MV砖码砖区2021在线| 欧美成人精品午夜免费影视| 国产精品一区二区久久乐下载 | 午夜无码一区二区三区在线| 乱人伦精品视频在线观看| 国产成人AV片无码免费| 又大又粗又爽又黄的少妇毛片 | 国产精品IGAO视频|