日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端也要会的数据结构 (不定期更新篇)

發(fā)布時間:2023/12/2 HTML 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端也要会的数据结构 (不定期更新篇) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前端的軟肋

一說到前端大家腦子里只有,布局、展示數(shù)據(jù)、修改樣式等等。可是數(shù)據(jù)是哪里來的呢?后端給的后端給的。數(shù)據(jù)的結(jié)構(gòu)呢?后端給啥用啥。

這就是前端的一個軟肋。我們的業(yè)務(wù)讓我們并不需要過深入的了解數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu)和算法是一個程序員的基礎(chǔ)。無論是前端開發(fā)還是后端開發(fā)、還是AI機器學習大數(shù)據(jù),我認為都需要一定的數(shù)據(jù)結(jié)構(gòu)和算法知識(除了前端,其余的都是強烈的剛需。。。),前端的伙伴們學會數(shù)據(jù)結(jié)構(gòu)有什么好處呢?改變思考方式,深入了解js執(zhí)行的一些過程,在代碼中不知不覺考慮代碼層面的性能優(yōu)化。用處很多,接下來開始吧。

什么是數(shù)據(jù)結(jié)構(gòu)?

數(shù)據(jù)結(jié)構(gòu)是計算機存儲、組織數(shù)據(jù)的方式。數(shù)據(jù)結(jié)構(gòu)是指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合。(來自百度百科)

計算機存儲是什么意思呢?就是我們常說的存儲結(jié)構(gòu)。

組織數(shù)據(jù)的方式與特定關(guān)系呢?就是我們的邏輯結(jié)構(gòu)。

一堆按一定的存儲結(jié)構(gòu)和邏輯結(jié)構(gòu)組合起來的數(shù)據(jù)集合就是數(shù)據(jù)結(jié)構(gòu)。

這是我的一些理解。所以當一種數(shù)據(jù)結(jié)構(gòu)擺在我的面前我就會考慮,它是以哪種形式存儲起來,它有什么特殊的邏輯組合起來。這種方式有哪些好處呢?當我明白這些的時候,這種數(shù)據(jù)結(jié)構(gòu)我就算基本了解了。

首先我們先說一下線性表,線性表是數(shù)據(jù)的邏輯結(jié)構(gòu),元素之間是一對一的關(guān)系,你個線性表中,任何一個元素的前一個或者后一個都只有一個元素,而不會出現(xiàn)任何一個元素的前一個或者后一個元素對應(yīng)多個元素的情況。

線性表分為一般性的線性表、與受限的線性表。一般性的線性表就好比數(shù)組。就是最常見的一般性線性表,而受限的線性表就是棧與隊列。

好了好了 我們開始正題了

你好 神奇的棧結(jié)構(gòu)

棧型結(jié)構(gòu),最大的特點是什么?先進后出,先進入的元素要比后進入的元素更晚的離開這個容器,這像什么一堆摞起來的書籍。你這能拿走書的最上面的。(你要是給書推倒了,那就只能說明你比較睿智)

所以我們要實現(xiàn)一個棧型結(jié)構(gòu)很自然的想到了

容器:數(shù)組

方法:數(shù)組的push與pop方法 下面開始實現(xiàn)一個棧的構(gòu)造函數(shù)

function Stack(){// 用let創(chuàng)建一個私有容器,無法用this選擇到dataStore;let dataStore = [];// 模擬進棧的方法 this.push = function(element){dataStore.push(element);};// 模擬出棧的方法,返回值是出棧的元素。this.pop = function(){return dataStore.pop();};// 返回棧頂元素this.peek = function(){return dataStore[dataStore.length-1]; };// 是否為空棧this.isEmpty = function(){return dataStore.length === 0 };// 獲取棧結(jié)構(gòu)的長度。this.size = function(){return dataStore.length;};// 清除棧結(jié)構(gòu)內(nèi)的所有元素。this.clear = function(){dataStore = [];} }

好了伙伴們 棧的構(gòu)造函數(shù)我們已經(jīng)寫好了。

// 一個單獨的棧生成了。 let stack = new Stack(); stack.push(1); stack.push(2); stack.push(5); stack.peek(); // return 5 stack.size(); // return 3 stack.clear(); stack.peek(); // undefined

一個基本的棧型結(jié)構(gòu)就實現(xiàn)了。 真的很是簡單。但是這個東西在js中有什么用處呢?

在js中的用處

用處很大,首先我們都知道遞歸如果沒有設(shè)置好邊界值,就會報堆棧溢出。 什么意思??? 我們的js代碼在執(zhí)行的時候,會生成一個調(diào)用棧(里面裝滿了所有執(zhí)行中的函數(shù))

在這個調(diào)用棧第一個進棧的也就是壓在最下面的就是全局函數(shù),這個全局函數(shù)只會在瀏覽器關(guān)閉后才會出棧,瀏覽器關(guān)閉了這個堆棧也就隨之消失了。 當瀏覽器執(zhí)行下去的時候執(zhí)行一個函數(shù)的時候,就會把這個執(zhí)行中的函數(shù)加入到調(diào)用棧中,被調(diào)用了就要進調(diào)用棧(比較好理解吧),同時控制權(quán)也會轉(zhuǎn)交給這個函數(shù),這個函數(shù)中如果有別的函數(shù),執(zhí)行到別的函數(shù)時,做著一樣的事情,進棧。當任何一個函數(shù)執(zhí)行結(jié)束之后,那么不好意思,他就要退棧了。離開這個調(diào)用棧了。因為調(diào)用棧中內(nèi)容過多,代表著垃圾資源沒有回收,從而導致瀏覽器卡頓,這是不合理的,執(zhí)行完畢就會退棧。

退棧之后,那么執(zhí)行權(quán)就要交回到包含著它的函數(shù)了。

堆棧的三種場景

1:遞歸是一種怎樣的情況呢?

當我們沒有考慮遞歸的出口的時候, 簡化函數(shù) function fn(){let a = 1; fn() } fn() // 報錯!!!! Maximum call stack size exceeded// 最大調(diào)用堆棧大小超過

當我沒有設(shè)定出口時,并沒有任何一個函數(shù)會出棧,在不斷的循環(huán)調(diào)用后,你的堆棧肯定不會是無限的,那么就只好提醒你堆棧溢出,程序報錯。

2: 你知道redux的洋蔥模型圖嗎?

所謂redux的洋蔥模型(其實redux我沒用過,但是在公司分享會上聽過一段對于這個洋蔥模型圖的分享),大家也可以理解一下express框架的寫接口時的next函數(shù)。

在我們洋蔥在最外層執(zhí)行完畢后就會進入里面,到最內(nèi)部后再循壞退出來。

function fn1(){console.log('fn1 first');fn2()console.log('fn1 last'); } function fn2(){console.log('fn2 first');fn3()console.log('fn2 last'); } function fn3(){console.log('fn3 first');console.log('fn3 last'); } fn1()

打印結(jié)果中我們可以看出,fn1執(zhí)行的時候在,遇到fn2執(zhí)行進棧后,將控制權(quán)轉(zhuǎn)交給fn2,fn2執(zhí)行遇到fn3執(zhí)行進棧,將控制權(quán)交給fn3,fn3執(zhí)行完畢后退棧,控制權(quán)還給fn2,那么fn2后面的代碼會繼續(xù)執(zhí)行,fn2的代碼執(zhí)行完畢,退棧。繼續(xù)執(zhí)行fn1后面的代碼直到退棧。可能這種簡單的模式大家看起來比較清晰,如果有比較復雜的內(nèi)容,大家記得畫圖不要弄錯了。

3: 不說你就會忘的閉包

為什么閉包使用過多會導致程序卡頓,性能不好???

這個問題很讓人費解,但是扯上調(diào)用棧后,我覺得可以解釋一波(代碼我就不上了,大家可以去找找閉包得代碼看一看) 閉包得私有變量怎么產(chǎn)生的? 在一個函數(shù)執(zhí)行后,它執(zhí)行完畢就一定會退棧。

function A(){var count = 0;function B(){count ;console.log(count);}return B; } var C = A(); C();// 1 C();// 2 C();// 3

不好意思我食言了,方便大家理解還是上一波代碼吧。

在A函數(shù)執(zhí)行得時候,我們發(fā)現(xiàn)執(zhí)行過程中,遇到B函數(shù),好了它開始調(diào)用進棧執(zhí)行,執(zhí)行完畢后,控制權(quán)回歸A函數(shù),然后把B函數(shù)return出去了。B函數(shù)中保持對count變量的引用,你就把它return出去了????好吧你愿意你就這么干。

B函數(shù)被推出去到外面的世界(外面的函數(shù)體內(nèi));將B賦值給C,好了C需要count變量的支持,count就不能離開內(nèi)存(也就是不能被垃圾回收);拿咋辦? A函數(shù)執(zhí)行完了我也該離開了(函數(shù)執(zhí)行完畢后,函數(shù)內(nèi)部的變量會被回收掉)。不好意思,外面執(zhí)行著的函數(shù)還有對你的引用,那不好意思你別退棧了,并不允許離開調(diào)用棧,因為要保留count變量的環(huán)境。

好吧每一個這種情況就會有幾個函數(shù)無法退棧,調(diào)用棧里面的內(nèi)容越堆越多。就會越加卡頓。一輛公交車,咱們的乘客到站就下車了,但是總有幾個乘客死活不下車,車上人越來越多,車也越來越沉,好吧跑起來就越來越慢了。

是時候結(jié)個尾了

在不理解棧的時候,我很難去想以上幾種情況,數(shù)據(jù)結(jié)構(gòu)真的在改變我的思路,一切的知識點都在這些基礎(chǔ)中有著驗證,夯實基礎(chǔ),我認為數(shù)據(jù)結(jié)構(gòu)也不應(yīng)該是前端的加分項,而是比會項。最后的最后,我用我聽過的一句很經(jīng)典的話來結(jié)尾好了

我們寫的代碼不是為了更好的和人去溝通,而是去更好的和機器溝通

最后打個廣告(我們一起維護的學習公眾號)

公眾號主要面向的是初級/應(yīng)屆生。內(nèi)容包含我們從應(yīng)屆生轉(zhuǎn)換為職場開發(fā)所踩過的坑,以及我們每周的學習計劃和學習總結(jié)。 內(nèi)容會涉及計算機網(wǎng)絡(luò)算法等基礎(chǔ);也會涉及前端,后臺,Android等內(nèi)容~

我們基友團其他朋友的文章:

Android基友

Java基友

總結(jié)

以上是生活随笔為你收集整理的前端也要会的数据结构 (不定期更新篇)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。