日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
如果我去參加前端面試,我應(yīng)該能做出大圣老師的這道題...

本文轉(zhuǎn)載自微信公眾號(hào)「Piper蛋窩」,作者Piper蛋。轉(zhuǎn)載本文請(qǐng)聯(lián)系Piper蛋窩公眾號(hào)。

成都創(chuàng)新互聯(lián)公司專(zhuān)注于紅旗企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城開(kāi)發(fā)。紅旗網(wǎng)站建設(shè)公司,為紅旗等地區(qū)提供建站服務(wù)。全流程按需定制制作,專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

我是一名自學(xué)敲代碼的管理學(xué)研究生,喜歡 js/ts 但是菜得不行,平常挺關(guān)注國(guó)內(nèi)的前端圈。

除了讀雪碧大佬[1]等等大佬的知乎外(蒟蒻還看不太懂),平常也看看大圣老師[2]等等的B站。

有一次看大圣老師直播點(diǎn)評(píng)簡(jiǎn)歷,他提到:“如果我來(lái)面試你,我就把我面前的筆記本給你,隨便給你打開(kāi)個(gè)網(wǎng)頁(yè)比如淘寶,你給我用瀏覽器現(xiàn)場(chǎng)統(tǒng)計(jì)一下各個(gè)標(biāo)簽出現(xiàn)的次數(shù)?!?/p>

!這道題應(yīng)該不難?我分析無(wú)非就是考察了三點(diǎn):

  • 最最基礎(chǔ)的瀏覽器調(diào)試能力
  • 算法能力
  • 基礎(chǔ)的 JavaScript API 應(yīng)用

剛和爸媽打完球回來(lái),那我就做做這道題。

首先咱捋一下思路:

  • 其實(shí)早在聽(tīng)到這個(gè)題目時(shí),我腦子中就蹦出兩個(gè)字:『遞歸』!
  • 畢竟,我們的網(wǎng)頁(yè)就是一棵 DOM 樹(shù),從根部有子節(jié)點(diǎn),子節(jié)點(diǎn)還有子節(jié)點(diǎn),對(duì)于每個(gè)節(jié)點(diǎn),我們能夠知道這個(gè)節(jié)點(diǎn)是什么標(biāo)簽并且對(duì)其子節(jié)點(diǎn)做同樣的事就可以了

然后我們捋一下需要哪些技術(shù)細(xì)節(jié):

  • 首先我們應(yīng)該獲取根節(jié)點(diǎn),這個(gè)好說(shuō),我們?cè)跒g覽器的控制臺(tái)里試一試就知道:document.children[0]
  • 然后我們應(yīng)該能夠獲取每個(gè)標(biāo)簽對(duì)象的字符串名字和子節(jié)點(diǎn)列表,分別是 tagName 和 children
  • 至于如何實(shí)現(xiàn)「遞歸」呢?這里未必要用到遞歸,我用的是寬度優(yōu)先搜索 BFS ,簡(jiǎn)單一個(gè)隊(duì)列就能實(shí)現(xiàn)

值得一提的是,我近一個(gè)月里寫(xiě)了基于 C++ 、Python 、 JavaScript/TypeScript 、 Scala/Java 的不同項(xiàng)目/小腳本(工作要求...),所以我也記不住 JavaScript 的 API ,我都是在瀏覽器控制臺(tái)里試出來(lái)的,比如 獲取標(biāo)簽的名字是 tagName 、 獲取子節(jié)點(diǎn) Array 是 children 。如下圖,我試關(guān)鍵詞試出來(lái)的,要不然誰(shuí)記得住啊。

輸入 tag 會(huì)不會(huì)得到我想要的 API 呢?果然!

下面動(dòng)手來(lái)做吧

第零步,打開(kāi)瀏覽器的 Sources ,新建一個(gè) Snippet 。

Sources

首先我不知道 JavaScript 里有沒(méi)有現(xiàn)成的隊(duì)列數(shù)據(jù)結(jié)構(gòu),應(yīng)該是沒(méi)有,那我就自己實(shí)現(xiàn)一個(gè)吧。

 
 
 
 
  1. class Queue { 
  2.     #array = [] 
  3.     constructor () { 
  4.         this.#array = [] 
  5.     } 
  6.  
  7.     top () { 
  8.         return this.#array[0] 
  9.     } 
  10.  
  11.     size () { 
  12.         return this.#array.length 
  13.     } 
  14.  
  15.     pop () { 
  16.         this.#array.shift() 
  17.     } 
  18.  
  19.     push (ele) { 
  20.         this.#array.push(ele) 
  21.     } 

很簡(jiǎn)單的封裝!我平時(shí)做算法題都是用 C++ ,所以這里方法的名稱(chēng)就都盡量接近 C++ 的 std::queue 。

接下來(lái)咱們寫(xiě) BFS 就行了!

我看現(xiàn)在大佬們都把每個(gè)邏輯封裝在函數(shù)里,所以咱也把腳本運(yùn)行邏輯 main() 里,然后再在外面調(diào)用一下 main() ,看著整潔點(diǎn)。

 
 
 
 
  1. const main = () => { 
  2.  
  3.     const dict = {} 
  4.     const queue = new Queue() 
  5.  
  6.     const htmlTag = document.children[0] 
  7.     dict[htmlTag.tagName] += 1  // !!! 
  8.     queue.push(htmlTag) 
  9.  
  10.     while (queue.size() > 0) { 
  11.         const t = queue.top() 
  12.         queue.pop() 
  13.  
  14.         for (let i = 0; i < t.children.length; i ++) { 
  15.             childTag = t.children[i] 
  16.             dict[htmlTag.tagName] += 1  // !!! 
  17.             queue.push(childTag) 
  18.         } 
  19.     } 
  20.  
  21.     for (let item in dict) { 
  22.         console.log(item, ': ', dict[item]) 
  23.     } 
  24.  
  25. main() 

上面是最最簡(jiǎn)單的 BFS 實(shí)現(xiàn)了,可見(jiàn)這道題著實(shí)不是用算法難為我們,很實(shí)在的一道題。

注意我標(biāo)注的 !!! 兩行,這里有一個(gè)問(wèn)題:

  • dict = {} 中,對(duì)于未聲明過(guò)的鍵值,如果直接調(diào)用運(yùn)算,會(huì)報(bào)錯(cuò) dict[未聲明的鍵值] +=1 // 報(bào)錯(cuò)!
  • 而 js 又不是 Python ,沒(méi)有 setdefault 給我們用比如 dict.setdefault(鍵值, 0); dict[鍵值] += 1
  • js 也不是 C++ ,直接默認(rèn)未出現(xiàn)過(guò)的鍵值的值為 0
  • 因此我們需要再寫(xiě)一個(gè) dict[未聲明的鍵值] +=1 功能

咱們把這個(gè)邏輯寫(xiě)成一個(gè) Effect ,返回一個(gè)函數(shù),以顯示咱很注重邏輯復(fù)用性(劃去)。

 
 
 
 
  1. const addDictEffect =  (dict) => { 
  2.     return (name) => { 
  3.         if (dict[name]) { 
  4.             dict[name] += 1 
  5.         } else { 
  6.             dict[name] = 1 
  7.         } 
  8.     } 

OK 那下面在修改一下 main ,一共有三處!

 
 
 
 
  1. const main = () => { 
  2.  
  3.     const dict = {} 
  4.     const addDict = addDictEffect(dict)  // 第一處! 
  5.     const queue = new Queue() 
  6.  
  7.     const htmlTag = document.children[0] 
  8.     addDict(htmlTag.tagName)  // 第二處! 
  9.     queue.push(htmlTag) 
  10.  
  11.     while (queue.size() > 0) { 
  12.         const t = queue.top() 
  13.         queue.pop() 
  14.  
  15.         for (let i = 0; i < t.children.length; i ++) { 
  16.             childTag = t.children[i] 
  17.             addDict(childTag.tagName)  // 第三處! 
  18.             queue.push(childTag) 
  19.         } 
  20.     } 
  21.  
  22.     for (let item in dict) { 
  23.         console.log(item, ': ', dict[item]) 
  24.     } 
  25.  
  26. main() 

啪!很快啊,本題目解決。www.taobao.com 結(jié)果如下。

代碼

結(jié)果

其他網(wǎng)頁(yè)均可測(cè)試。

完整代碼

 
 
 
 
  1. class Queue { 
  2.     #array = [] 
  3.     constructor () { 
  4.         this.#array = [] 
  5.     } 
  6.  
  7.     top () { 
  8.         return this.#array[0] 
  9.     } 
  10.  
  11.     size () { 
  12.         return this.#array.length 
  13.     } 
  14.  
  15.     pop () { 
  16.         this.#array.shift() 
  17.     } 
  18.  
  19.     push (ele) { 
  20.         this.#array.push(ele) 
  21.     } 
  22.  
  23. const addDictEffect =  (dict) => { 
  24.     return (name) => { 
  25.         if (dict[name]) { 
  26.             dict[name] += 1 
  27.         } else { 
  28.             dict[name] = 1 
  29.         } 
  30.     } 
  31.  
  32. const main = () => { 
  33.  
  34.     const dict = {} 
  35.     const addDict = addDictEffect(dict) 
  36.     const queue = new Queue() 
  37.  
  38.     const htmlTag = document.children[0] 
  39.     addDict(htmlTag.tagName) 
  40.     queue.push(htmlTag) 
  41.  
  42.     while (queue.size() > 0) { 
  43.         const t = queue.top() 
  44.         queue.pop() 
  45.  
  46.         for (let i = 0; i < t.children.length; i ++) { 
  47.             childTag = t.children[i] 
  48.             addDict(childTag.tagName) 
  49.             queue.push(childTag) 
  50.         } 
  51.     } 
  52.  
  53.     for (let item in dict) { 
  54.         console.log(item, ': ', dict[item]) 
  55.     } 
  56.  
  57. main() 

目前不會(huì)js/ts+沒(méi)做過(guò)項(xiàng)目,菜到都沒(méi)法給大圣老師發(fā)簡(jiǎn)歷讓他點(diǎn)評(píng)。期待早日能到發(fā)簡(jiǎn)歷的地步。


當(dāng)前文章:如果我去參加前端面試,我應(yīng)該能做出大圣老師的這道題...
URL鏈接:http://www.5511xx.com/article/cojhsii.html