最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一個(gè)關(guān)于JS操作符in問題引發(fā)的探究

 更新時(shí)間:2021年04月13日 11:04:35   作者:恪愚  
這篇文章主要給大家介紹了一個(gè)JS操作符in問題引發(fā)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

事情是這樣的:大家都知道“內(nèi)存泄露”這回事吧。它有幾個(gè)常見的場景:

  • 閉包使用不當(dāng)引起內(nèi)存泄漏
  • (未聲明的)全局變量
  • 分離的DOM節(jié)點(diǎn)
  • (隨意的)控制臺的打印
  • 遺忘的定時(shí)器
  • 循環(huán)引用

內(nèi)存泄漏需要重視,它是如此嚴(yán)重甚至?xí)?dǎo)致頁面卡頓,影響用戶體驗(yàn)!

其中第 3 點(diǎn)引起了我的注意 —— 我當(dāng)然清楚地知道它說的是比如:“假設(shè)你手動移除了某個(gè)dom節(jié)點(diǎn),本應(yīng)釋放該dom節(jié)點(diǎn)所占用的內(nèi)存,但卻因?yàn)槭韬鰧?dǎo)致某處代碼仍對該被移除節(jié)點(diǎn)有引用,最終導(dǎo)致該節(jié)點(diǎn)所占內(nèi)存無法被釋放”的情況

<div id="root">
    <div class="child">我是子元素</div>
    <button>移除</button>
</div>
<script>
    let btn = document.querySelector('button')
    let child = document.querySelector('.child')
    let root = document.querySelector('#root')
    
    btn.addEventListener('click', function() {
        root.removeChild(child)
    })

</script>

該代碼所做的操作就是點(diǎn)擊按鈕后移除.child的節(jié)點(diǎn),雖然點(diǎn)擊后,該節(jié)點(diǎn)確實(shí)從dom被移除了,但全局變量child仍對該節(jié)點(diǎn)有引用,所以導(dǎo)致該節(jié)點(diǎn)的內(nèi)存一直無法被釋放。

解決辦法:我們可以將對.child節(jié)點(diǎn)的引用移動到click事件的回調(diào)函數(shù)中,那么當(dāng)移除節(jié)點(diǎn)并退出回調(diào)函數(shù)的執(zhí)行上文后就會自動清除對該節(jié)點(diǎn)的引用,自然也就不會存在內(nèi)存泄漏的情況了。(這實(shí)際上是在事件中實(shí)時(shí)檢測該節(jié)點(diǎn)是否存在,如果不存在則瀏覽器必不會觸發(fā)remove函數(shù)的執(zhí)行)

<div id="root">
    <div class="child">我是子元素</div>
    <button>移除</button>
</div>
<script>
    let btn = document.querySelector('button')

    btn.addEventListener('click', function() {  
        let child = document.querySelector('.child')
        let root = document.querySelector('#root')

        root.removeChild(child)
    })

</script>

這段代碼很完美么?不。因?yàn)樗诿看问录|發(fā)后都創(chuàng)建了對child和root節(jié)點(diǎn)的引用。消耗了內(nèi)存(你完全可以想象一些人會狂

點(diǎn)按鈕的情況…)。

其實(shí)還有一種辦法:我們在click中去判斷當(dāng)前root節(jié)點(diǎn)中是否還存在child子節(jié)點(diǎn),如果存在,則執(zhí)行remove函數(shù),否則什么也不做!

這就引發(fā)了標(biāo)題中所說的行為。

怎么判斷?

遍歷?不,太過麻煩!

不知怎的,我突然想到了 for...in 中的 in 操作符,它可以基于原型鏈遍歷對象!

我們來還原一下當(dāng)時(shí)的場景:打開GitHub,隨便找一個(gè)父節(jié)點(diǎn),并獲取它:

mygithub

圖中畫紅框的就是我們要取的父元素,橘紅色框的就是要判斷是否存在的子元素。

let parent=document.querySelector('.position-relative');
let child=document.querySelector('.progress-pjax-loader');

這里注意,因?yàn)楂@取到的是DOM節(jié)點(diǎn)(類數(shù)組對象),所以我們在操作前一定要先處理一下:

object

let p_child=[...parent.children];

array

然后

console.log(child in p_child);

not

?。?!

為什么呢?(此時(shí)筆者還沒有意識到事情的嚴(yán)重性)

我想,是不是哪里出了問題,用es6的includes API驗(yàn)證一下:

console.log(p_child.includes(child));

yes

沒錯(cuò)啊!

再用一般的數(shù)組驗(yàn)證一下:

Verification

???

此時(shí),筆者才想起到MDN上查閱一番:

mdn

進(jìn)而我發(fā)現(xiàn):in操作符單獨(dú)使用時(shí)它檢測的是左側(cè)的值(作為索引)對應(yīng)的值是否在右側(cè)的對象內(nèi)部(屬性 & 原型上)!

回到上面的代碼中,我們發(fā)現(xiàn):

vertification_2

這驗(yàn)證了我們的結(jié)論。

很顯然,“子元素”并不等同于“存在于原型鏈上” —— 這又引出了一個(gè)知識點(diǎn):attribute和property的區(qū)別!

所以經(jīng)過一番“折騰”,源代碼還是應(yīng)該直接這樣寫:

<div id="root">
    <div class="child">我是子元素</div>
    <button>移除</button>
</div>
<script>
    let btn = document.querySelector('button')
    let child = document.querySelector('.child')
    let root = document.querySelector('#root')
    let r_child = [...root.children]
    
    btn.addEventListener('click', function() {
        if(r_child.includes(child)){   // 或者你這里直接判斷child是否為null也可以...吧
        	root.removeChild(child)
        }
    })

</script>

略顯倉促的結(jié)尾

所以,看書學(xué)習(xí)有時(shí)候并不能“不求甚解”~

還要勇于“折騰”,學(xué)會“查文檔”[/滑稽臉].

總結(jié)

到此這篇關(guān)于一個(gè)關(guān)于JS操作符in問題的文章就介紹到這了,更多相關(guān)JS操作符in問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解JS中的微任務(wù)和宏任務(wù)的執(zhí)行順序及應(yīng)用場景

    深入理解JS中的微任務(wù)和宏任務(wù)的執(zhí)行順序及應(yīng)用場景

    JavaScript中的任務(wù)分為宏任務(wù)和微任務(wù),它們的執(zhí)行順序會影響代碼的執(zhí)行結(jié)果。了解它們的機(jī)制可以幫助我們更好地理解事件循環(huán)和異步編程,避免出現(xiàn)一些意想不到的錯(cuò)誤
    2023-05-05
  • js獲取地址欄參數(shù)的兩種方法

    js獲取地址欄參數(shù)的兩種方法

    這篇文章主要為大家詳細(xì)介紹了js獲取地址欄參數(shù)的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Node.js實(shí)戰(zhàn) 建立簡單的Web服務(wù)器

    Node.js實(shí)戰(zhàn) 建立簡單的Web服務(wù)器

    本章我們同樣通過實(shí)戰(zhàn)的演練,利用Node.js建立一個(gè)簡單的Web服務(wù)器
    2012-03-03
  • js innerHTML 的一些問題的解決方法

    js innerHTML 的一些問題的解決方法

    innerHTML 屬性的使用非常流行,因?yàn)樗峁┝撕唵蔚姆椒ㄍ耆娲粋€(gè) HTML 元素的內(nèi)容。另外一個(gè)方法是使用 DOM Level 2 API(removeChild, createElement, appendChild)。但很顯然,使用 innerHTML 修改 DOM tree 是非常容易且有效的方法。
    2008-06-06
  • 使用JS畫圖之點(diǎn)、線、面

    使用JS畫圖之點(diǎn)、線、面

    這篇文章主要介紹了使用js繪制幾何圖形的基礎(chǔ),繪制點(diǎn)、線、面,需要的朋友可以參考下
    2015-01-01
  • jquery刪除ID為sNews的tr元素的內(nèi)容

    jquery刪除ID為sNews的tr元素的內(nèi)容

    這篇文章主要介紹了刪除ID為sNews的索引為JQID的tr元素里的內(nèi)容,需要的朋友可以參考下
    2014-04-04
  • js防抖-節(jié)流函數(shù)的基本實(shí)現(xiàn)和補(bǔ)充詳解

    js防抖-節(jié)流函數(shù)的基本實(shí)現(xiàn)和補(bǔ)充詳解

    這篇文章主要介紹了防抖-節(jié)流函數(shù)的基本實(shí)現(xiàn)和補(bǔ)充,文章從基礎(chǔ)概念到手寫對防抖-節(jié)流函數(shù)的實(shí)現(xiàn)進(jìn)行講解,內(nèi)容詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-01-01
  • 使用?TypeScript?開發(fā)?React?函數(shù)式組件

    使用?TypeScript?開發(fā)?React?函數(shù)式組件

    這篇文章主要介紹了使用?TypeScript開發(fā)React函數(shù)式組件,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-08-08
  • leaflet基本使用示例教程

    leaflet基本使用示例教程

    這篇文章主要介紹了leaflet基本使用示例教程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • 微信小程序中實(shí)現(xiàn)埋點(diǎn)的方法示例詳解

    微信小程序中實(shí)現(xiàn)埋點(diǎn)的方法示例詳解

    在小程序中實(shí)現(xiàn)埋點(diǎn)的基本思路是利用生命周期函數(shù)和事件回調(diào),插入數(shù)據(jù)上報(bào)代碼,下面將介紹如何在小程序中實(shí)現(xiàn)埋點(diǎn),并通過代碼示例進(jìn)行說明,感興趣的朋友一起看看吧
    2024-04-04

最新評論

嘉义县| 尖扎县| 诏安县| 庆元县| 平泉县| 荔浦县| 黑龙江省| 福建省| 贵德县| 石渠县| 浮山县| 扶风县| 河北省| 湖州市| 东兴市| 静海县| 益阳市| 昭平县| 津南区| 湖北省| 晋州市| 嘉黎县| 永年县| 合阳县| 喜德县| 金昌市| 鄂尔多斯市| 连山| 平陆县| 临安市| 惠安县| 华宁县| 景德镇市| 崇礼县| 中西区| 绥滨县| 西吉县| 额济纳旗| 柘荣县| 通道| 清丰县|