<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一份沉甸甸的大廠面經(jīng)

          共 18977字,需瀏覽 38分鐘

           ·

          2021-03-02 12:49


          關(guān)注公眾號(hào) 前端人,回復(fù)“加群

          添加無廣告優(yōu)質(zhì)學(xué)習(xí)群

          js 基礎(chǔ)

          手寫 reduce

          Array.prototype.myReduce = function (fn,initVal{
              let result = initVal,
                  i = 0;
              if (typeof initVal === 'undefined') {
                  result = this[i]
                  i++;
              }

              while(i < this.length) {
                 result =  fn(result, this[i])
              }
              return result
          }

          手寫 Promise.all

          Promise.prototype.myAll = function (promiseArray{
              return new Promise((resolve,reject) => {
                  if (promiseArray.length === 0) {
                      return resolve([])
                  } else {
                      let res = [],count=0
                       for (let i = 0; i < arr.length; i++) {
                       // 同時(shí)也能處理arr數(shù)組中非Promise對(duì)象
                          if (!(promiseArray[i] instanceof Promise)) {
                              res[i] = promiseArray[i]
                              if (++count === promiseArray.length)
                                  resolve(res)
                          } else {
                              promiseArray[i].then(data => {
                                  res[i] = data
                                  if (++count === promiseArray.length)
                                      resolve(res)
                              }, err => {
                                  reject(err)
                              })
                          }
                      }
                  }
              })
          }

          requestAnimationFrame

          優(yōu)勢(shì):目的是為了讓各種網(wǎng)頁動(dòng)畫效果(DOM動(dòng)畫、Canvas動(dòng)畫、SVG動(dòng)畫、WebGL動(dòng)畫)能夠有一個(gè)統(tǒng)一的刷新機(jī)制,從而節(jié)省系統(tǒng)資源,提高系統(tǒng)性能,改善視覺效果。使用這個(gè)API就是告訴瀏覽器希望執(zhí)行一個(gè)動(dòng)畫,讓瀏覽器在下一個(gè)動(dòng)畫幀安排一次網(wǎng)頁重繪。

          • requestAnimationFrame會(huì)把每一幀中的所有DOM操作集中起來,在一次重繪或回流中完成,并且重繪或回流的時(shí)間間隔是跟隨瀏覽器的刷新頻率
          • 在隱藏或不可見的元素中,requestAnimationFrame將不會(huì)進(jìn)行重繪或回流,這意味著更少的cpu,gpu和內(nèi)存的使用量。

          promise

          是異步編程的一種解決方案,解決了回調(diào)地獄的問題。

          特點(diǎn):

          • 對(duì)象的狀態(tài)狀態(tài)不受外界影響。Promise對(duì)象代表一個(gè)異步操作,有三種狀態(tài):pending、fulfilled、rejected。只有異步操作的結(jié)果可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個(gè)狀態(tài)
          • 一旦狀態(tài)改變,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果

          Promise也有一些缺點(diǎn)。首先,無法取消Promise,一旦新建它就會(huì)立即執(zhí)行,無法中途取消。其次,如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。第三,當(dāng)處于pending狀態(tài)時(shí),無法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)。

          async/await

          async 函數(shù)就是Generator函數(shù)的語法糖。

          優(yōu)點(diǎn):

          1. 內(nèi)置執(zhí)行器
          2. 更好的語義
          3. 更廣是適用性
          4. 返回值是 Promise await命令就是內(nèi)部 then 命令的語法糖

          arguments 對(duì)象

          arguments對(duì)象是函數(shù)中的局部變量,他擁有 lenth屬性和索引元素,但沒有數(shù)組的其他屬性

          創(chuàng)建對(duì)象的7種方法

          • 通過Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建單個(gè)對(duì)象
          • 工廠模式
          • 構(gòu)造函數(shù)模式
          • 原型模式
          • 組合使用構(gòu)造函數(shù)模式和原型模式
          • 動(dòng)態(tài)原型模式
          • Object.create()

          工廠模式

          function Person({
            var o = new Object();
            o.name = 'hanmeimei';
            o.say = function({
              alert(this.name);
            }
            return o;
          }
          var person1 = Person();
          • 優(yōu)點(diǎn):完成了返回一個(gè)對(duì)象的要求
          • 缺點(diǎn):
            1. 無法通過constructor識(shí)別對(duì)象,以為都是來自O(shè)bject,無法得知來自Person
            2. 每次通過Person創(chuàng)建對(duì)象的時(shí)候,所有的say方法都是一樣的,但是卻存儲(chǔ)了多次,浪費(fèi)資源

          裝飾器

          裝飾器是一種特殊的聲明,可附加在類、方法、訪問器、屬性、參數(shù)聲明上。

          作用:它起到了以聲明式方法將元信息添加至已有代碼的作用。

          函數(shù)柯里化

          是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。

          function curry(fn, args = []{
              return function ({
                  let rest = [...args, ...arguments]
                  if (rest.length < fn.length) {
                      return curry.call(this, fn, rest)
                  } else {
                      return fn.apply(this, rest)
                  }
              }
          }

          DOM

          node.nodeType 節(jié)點(diǎn)類型常量

          常量描述
          Node.ELEMENT_NODE1一個(gè)元素節(jié)點(diǎn) < p>/< div>
          Node.TEXT_NODE3Element或Attr中實(shí)際的文字
          Node.CDATA_SECTION_NODE4一個(gè) CDATASection,例如 <!CDATA[[ … ]]>
          Node.PROCESSING_INSTRUCTION_NODE一個(gè)用于XML文檔的 ProcessingInstruction ,例如 < ?xml-stylesheet ... ?> 聲明。
          Node.COMMENT_NODE8一個(gè) comment 節(jié)點(diǎn)。
          Node.DOCUMENT_NODE9一個(gè) Document 節(jié)點(diǎn)。
          Node.DOCUMENT_TYPE_NODE10描述文檔類型的DocumentType節(jié)點(diǎn)。
          Node.DOCUMENT_FRAGMENT_NODE11一個(gè)DocumentFragment節(jié)點(diǎn)

          typescript

          設(shè)計(jì)泛型的關(guān)鍵目的是在成員之間提供有意義的約束,這些成員可以是:

          1. 類的實(shí)例成員
          2. 類的方法
          3. 函數(shù)參數(shù)
          4. 函數(shù)返回值

          Hybrid

          h5 與 Native 通信方式?

          1. jsBridge

            • WebViewJavaScriptBridge的基本原理簡(jiǎn)單來說就是,建立一個(gè)橋梁,然后注冊(cè)自己,調(diào)用他人
          2. Scheme

            • 通過與app端約定協(xié)議名稱,app端定義協(xié)議對(duì)應(yīng)的方法,web端通過 window.location = 協(xié)議名稱的方式 通信
          3. websocket

          ios 與 android 兼容性問題

          line-height 顯示效果不一致問題

          在部分安卓機(jī)下設(shè)置line-height與高度相等時(shí)顯示不居中

          input輸入框聚焦

          input 輸入框在聚焦的時(shí)候,ios有時(shí)候會(huì)出現(xiàn) outline或者陰影,安卓則顯示正常 解決方案:input:focus{outline:none} input:{-webkit-appearance: none;}

          ios系統(tǒng)會(huì)將數(shù)字當(dāng)成電話號(hào)碼,導(dǎo)致變色

          <meta name="format-detection" content="telephone=no"> <meta http-equiv="x-rim-auto-match" content="none">

          安卓手機(jī)可以點(diǎn)擊圖片

          部分的安卓手機(jī)可以點(diǎn)擊頁面的圖片,解決方案就是通過css3給img標(biāo)簽設(shè)置不可點(diǎn)擊屬性。

          img{ pointer-events: none; }

          weex 原理

          1. 將vue單文件打包成 js bundle
          2. 客戶端打開某一個(gè)頁面,執(zhí)行 js bundle
          3. 客戶端提供了 js的執(zhí)行引擎 用于執(zhí)行加載到的 jsbundle
          4. js執(zhí)行引擎執(zhí)行 js Bundle,生成VNode樹進(jìn)行patch,找出最小操作DOM節(jié)點(diǎn)的操作,把對(duì)DOM的操作轉(zhuǎn)變?yōu)镹ative DOM API,調(diào)用 WXBridge進(jìn)行通信
          5. WXBridge將渲染指令分發(fā)到 Native(Android、iOS)渲染引擎,由native 渲染引擎完成最終的頁面渲染

          看完上述整體流程后,可以大致理解為何WEEX可以達(dá)到媲美原生的體驗(yàn),因?yàn)槠漤撁驿秩静⒉皇窍馠5方案一樣使用瀏覽器的渲染能力,而是原生渲染,所以本質(zhì)上渲染出來的頁面就是一個(gè)native頁面。

          flutter 原理

          flutter 采用自繪 ui + 原生的方式,通過在不同平臺(tái)實(shí)現(xiàn)一個(gè)統(tǒng)一的接口的渲染引擎來繪制UI,而不依賴系統(tǒng)原色控件,所以可以做到不同平臺(tái)UI的一致性。注意,自繪引擎解決的是UI的跨平臺(tái)問題,如果涉及其他系統(tǒng)能力調(diào)用,依然要涉及原生開發(fā)。

          優(yōu)點(diǎn):

          • 性能高:由于自繪引擎是直接調(diào)用系統(tǒng)API來繪制UI,所以性能和原生控件接近。
          • 靈活、組件庫易維護(hù)、UI外觀保真度和一致性高:由于UI渲染不依賴原生控件,也就不需要根據(jù)不同平臺(tái)的控件單獨(dú)維護(hù)一套組件庫,所以代碼容易維護(hù)。由于組件庫是同一套代碼、同一個(gè)渲染引擎,所以在不同平臺(tái),組件顯示外觀可以做到高保真和高一致性;另外,由于不依賴原生控件,也就不會(huì)受原生布局系統(tǒng)的限制,這樣布局系統(tǒng)會(huì)非常靈活。不足:

          動(dòng)態(tài)性不足:為了保證UI繪制性能,自繪UI系統(tǒng)一般會(huì)采用AOT模式編譯其發(fā)布包,所以應(yīng)用發(fā)布后,不能像Hybrid和RN那些使用JavaScript作為開發(fā)語言的框架那樣動(dòng)態(tài)下發(fā)代碼。

          瀏覽器

          同源策略

          同源策略是一個(gè)重要的安全策略,它用于限制一個(gè)origin 的文檔或者它加載的腳本如何能與另一個(gè)源的資源進(jìn)行交互。它能幫助組個(gè)惡意文檔,減少可能被攻擊的媒介。

          同源的定義

          如果兩個(gè)url的 協(xié)議,域名,端口號(hào)都相同,則兩個(gè)url同源。

          源的修改

          腳本可以將 document.domain 的值設(shè)置為其當(dāng)前域或其當(dāng)前域的父域。

          跨源網(wǎng)絡(luò)訪問

          同源策略控制不同源之間的交互,例如在使用XMLHttpRequest 或 < img> 標(biāo)簽時(shí)則會(huì)受到同源策略的約束

          跨源數(shù)據(jù)存儲(chǔ)訪問

          • 訪問存儲(chǔ)在瀏覽器中的數(shù)據(jù),如 localStorage 和 IndexedDB,是以源進(jìn)行分割。每個(gè)源都擁有自己?jiǎn)为?dú)的存儲(chǔ)空間,一個(gè)源中的 JavaScript 腳本不能對(duì)屬于其它源的數(shù)據(jù)進(jìn)行讀寫操作。如果一個(gè)頁面包含多個(gè)iframe且他們屬于同源頁面,那么他們之間是可以共享sessionStorage的。

          • 瀏覽器存儲(chǔ)均不支持跨域

          Vue

          組件的 data 為何要用 function 返回一個(gè)對(duì)象

          為了保證組件在復(fù)用時(shí)數(shù)據(jù)是相互隔離的,所以每個(gè)被服用的組件的 data 都是復(fù)制的一份新的對(duì)象僅供當(dāng)前組件使用,當(dāng)某一處的組件內(nèi)的data數(shù)據(jù)被改變時(shí),其他服用的

          數(shù)組響應(yīng)式監(jiān)聽

          在數(shù)據(jù)初始化的時(shí)候 vue會(huì)判斷屬性值是否是數(shù)組 ,如果是數(shù)組會(huì)遍歷數(shù)組的屬性循環(huán)調(diào)用 observe 將數(shù)組中的所有屬性轉(zhuǎn)換成響應(yīng)式

          同時(shí),對(duì)數(shù)組的原生API做劫持,當(dāng)使用數(shù)組的原生APi修改數(shù)組時(shí)會(huì)手動(dòng)執(zhí)行dep.notify()

          響應(yīng)式原理

          nextTick

          可以讓我們?cè)谙麓?DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào),用于獲得更新后的 DOM 同時(shí)在Vue內(nèi)部更新render時(shí)也是調(diào)用了nextTick使得多次set的觸發(fā)會(huì)再下次微任務(wù)中統(tǒng)一執(zhí)行。

          provide/inject

          這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時(shí)間里始終生效

          提示:provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個(gè)可監(jiān)聽的對(duì)象,那么其對(duì)象的屬性還是可響應(yīng)的。

          性能

          如何做首屏優(yōu)化

          1. 路由懶加載 :當(dāng)打包構(gòu)建應(yīng)用時(shí),JavaScript包會(huì)變得非常大,影響頁面加載。如果我們能把不同路由對(duì)應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問的時(shí)候才加載對(duì)應(yīng)組件,這樣就更加高效了。
          2. 框架和模塊按需引入
          3. 開啟gzip
          4. 框架和插件從cdn中引入:可以配置 webpack 的 externals

          為什么 react和Vue 一定要用 vnode?

          1. vnode 是 DOM的描述對(duì)象,操作Vnode比操作DOM更方便
          2. 直接操作DOM會(huì)頻繁的觸發(fā)瀏覽器的重排和重繪,而操作Vnode則不會(huì)
          3. 大量的重排和重繪會(huì)導(dǎo)致瀏覽器頻繁的更新DOM樹和CSSOM以及生成RENDER樹,對(duì)性能消耗很大

          當(dāng)需要大量數(shù)據(jù)渲染,在交互時(shí)點(diǎn)擊其中一行需要通知所有的行,如何做性能優(yōu)化?

          頁面性能監(jiān)控指標(biāo)

          根據(jù)谷歌 RAIL模型分為4個(gè)部分

          1. Response
          2. Animation
          3. Idle
          4. Load 分別代表著web應(yīng)用的生命周期的四個(gè)不同方面。最好的性能指標(biāo)是:100ms內(nèi)響應(yīng)用戶輸入;動(dòng)畫或者滾動(dòng)需在10ms內(nèi)產(chǎn)生下一幀;最大化空閑時(shí)間;頁面加載時(shí)長(zhǎng)不超過5秒。

          細(xì)分一下就是

          1. FP/FCP
          2. FMP
          3. LCP

          FP/FCP

          表示首次渲染、首次有內(nèi)容的渲染

          網(wǎng)絡(luò)

          從輸入url到頁面加載完成的過程

          1. 首先是dns查詢
          2. 假設(shè)服務(wù)端會(huì)響應(yīng)一個(gè) HTML 文件
          3. 首先瀏覽器會(huì)判斷狀態(tài)碼是什么,如果是200就繼續(xù)解析
          4. 文件解碼成功后開始渲染流程,先根據(jù)html創(chuàng)建dom,有css的話會(huì)去構(gòu)建cssom樹,如果遇到script標(biāo)簽,會(huì)判斷是否存在async 或defer ,前者會(huì)并行進(jìn)行下載并執(zhí)行js,后者會(huì)先下載文件,然后等待html解析完成后順序執(zhí)行,如果以上都沒有,就會(huì)阻塞住渲染流程直至js執(zhí)行完畢。遇到文件下載的會(huì)去下載文件
          5. 初始html被完全加載和解析后會(huì)觸發(fā) DOMContentLoaded 事件
          6. CSSOM 樹和DOM樹構(gòu)建完成后會(huì)開始生成Render樹,這一步就是確定頁面元素的布局、樣式等等諸多方面的東西
          7. 在生成Render樹的過程中,瀏覽器就開始調(diào)用GPU繪制,合成圖層,將內(nèi)容顯示到屏幕上

          https協(xié)議的過程

          1. 客戶端向服務(wù)端發(fā)起HTTPS請(qǐng)求,連接到服務(wù)器的443端口
          2. 服務(wù)器端有一個(gè)密鑰對(duì),即公鑰和私鑰,服務(wù)端保存著私鑰,公鑰可以發(fā)送給任何人。
          3. 服務(wù)器將自己的公鑰發(fā)給客戶端。
          4. 驗(yàn)證服務(wù)端發(fā)送的數(shù)字證書的合法性,驗(yàn)證通過后客戶端會(huì)生成一個(gè)隨機(jī)值,這個(gè)隨機(jī)值就是用于進(jìn)行對(duì)稱加密的密鑰,然后用用服務(wù)器的公鑰對(duì)隨機(jī)值進(jìn)行非對(duì)稱加密。這樣客戶端的密鑰就變成了密文。
          5. 客戶端再次發(fā)起http請(qǐng)求,將加密之后的客戶端密鑰發(fā)送給服務(wù)端
          6. 服務(wù)器接收到客戶端發(fā)來的密文之后,會(huì)用自己的私鑰對(duì)其進(jìn)行非對(duì)稱解密,解密之后的明文就是客戶端密鑰(隨機(jī)值),然后用隨機(jī)值對(duì)數(shù)據(jù)進(jìn)行對(duì)稱加密,這樣數(shù)據(jù)就變成了密文
          7. 然后服務(wù)器將加密后的數(shù)據(jù)發(fā)送給客戶端
          8. 客戶端收到服務(wù)器發(fā)來的密文,用客戶端密鑰對(duì)其進(jìn)行對(duì)稱解密,得到服務(wù)器發(fā)送的數(shù)據(jù)。傳輸完成

          node

          node異常處理方法

          1. 同步代碼中的異常使用try{}catch結(jié)構(gòu)即可捕獲處理。
          2. process的uncaughtException事件

          那異步錯(cuò)誤該怎么處理呢?首先換個(gè)思維,因?yàn)楫惓2⒉皇鞘孪葴?zhǔn)備好的,不能控制其到底在哪兒發(fā)生,所以站更高的角度,如監(jiān)聽?wèi)?yīng)用進(jìn)程的錯(cuò)誤異常,從而捕獲不能預(yù)料的錯(cuò)誤異常,保證應(yīng)用不至于奔潰掉。

          process.on('uncaughtException', (e)=>{  
            console.error('process error is:', e.message);
          });

          process.on('uncaughtException')的做法,很難去保證不造成內(nèi)存的泄漏。所以當(dāng)捕獲到異常時(shí),顯式的手動(dòng)殺掉進(jìn)程,并開始重啟node進(jìn)程,即保證釋放內(nèi)存,又保證了保證服務(wù)后續(xù)正常可用。3. 使用domain模塊

          Domain 模塊可分為隱式綁定和顯式綁定:隱式綁定: 把在domain上下文中定義的變量,自動(dòng)綁定到domain對(duì)象 顯式綁定: 把不是在domain上下文中定義的變量,以代碼的方式綁定到domain對(duì)象

          domin明顯的優(yōu)點(diǎn),能把出問題時(shí)的一些信息傳遞給錯(cuò)誤處理函數(shù),可以做一些打點(diǎn)上報(bào)等處理工作,最起碼保證重啟后的服務(wù),程序猿們知道發(fā)生了什么,有線索可查,也可以選擇傳遞上下文進(jìn)去,做一些后續(xù)處理。比如當(dāng)服務(wù)出錯(cuò)的時(shí)候,可以把用戶請(qǐng)求棧信息傳給下游,返回告知用戶服務(wù)異常,而不是用戶一直等到請(qǐng)求自動(dòng)超時(shí)。

          但是它和process.on('uncaughtException')的做法一樣,很難去保證不造成內(nèi)存的泄漏。

          一種比較好的方案是,以多進(jìn)程(cluster)的模式去部署應(yīng)用,當(dāng)某一個(gè)進(jìn)程被異常捕獲后,可以做一下打點(diǎn)上報(bào)后,開始重啟釋放內(nèi)存,此時(shí)其他請(qǐng)求被接受后,其他進(jìn)程依舊可以對(duì)外提供服務(wù),當(dāng)然前提是你的應(yīng)用不能異常多的數(shù)都數(shù)不清。

          將cluster和domain結(jié)合起來使用,以多進(jìn)程的方式保證服務(wù)可用,同時(shí)可以將錯(cuò)誤信息傳遞下去進(jìn)行上報(bào),并且保留錯(cuò)誤出現(xiàn)的上下文環(huán)境,給用戶返回請(qǐng)求,不讓用戶請(qǐng)求超時(shí),然后在手動(dòng)殺死異常進(jìn)程,然后重啟。

          express 與 koa的區(qū)別

          用法的區(qū)別

          • express是基于回調(diào),也是node中最常見的error-first模式
          • Koa使用Async/Await實(shí)現(xiàn)異步方式

          中間件的區(qū)別

          • express 中間件是線性模型
          • koa 中間件是洋蔥圈模型

          集成度

          • express自帶了Router和static中間件
          • Koa需要自行安裝Router和Static的中間件

          數(shù)據(jù)結(jié)構(gòu)與算法

          數(shù)組去重

          實(shí)現(xiàn)千位加逗號(hào)

          var a = 222333444.12
          function addDou(num{
               var numArr = num.split('.')
               num = numArr[0]
               var result = ''
               while(num.length>3){
                   result = ','+num.slice(-3)+result
                   num = num.slice(0,num.length-3)
               }
               if(num){
                   result = num+result
               }
               result = result+'.'+numArr[1]
               return result
           }
           console.log(addDou(a.toString()))

          正則版

          function addDou (num{
              num = num + ''
              let numArr = num.split('.')

              return numArr[0].replace(/(\d)(?=(\d{3})+$)/g'$1,')
          }

          字符串排列

          輸入'abc'輸出['abc','acb','bac','bca','cab','cba']

          思路

          • 本文章只研究全排列的情況,比如,還是 abc 字符串,3個(gè)字符,則總共的排列組合方式應(yīng)該有 n! 種,此處的 n 為3,則計(jì)算出來應(yīng)該是6種。本文采用遞歸方式實(shí)現(xiàn),基本思路是通過雙循環(huán)來實(shí)現(xiàn)遞歸的主邏輯部分,外層循環(huán) str,內(nèi)層循環(huán) n - 1 時(shí)的返回?cái)?shù)組 preResult 部分,算法邏輯如下方流程圖。
          • 首先,考慮遞歸如何產(chǎn)生,假如當(dāng) n = 1,即傳參 str 的長(zhǎng)度只有1時(shí),則直接返回只有 str 的數(shù)組;當(dāng) n > 1時(shí),則考慮 n 和 n - 1 方法返回?cái)?shù)組的關(guān)系。可以想到,n 時(shí)多出的一個(gè)字符,來添加到 n - 1 返回?cái)?shù)組中每個(gè)字符串的頭部。
          var perm = function(s{
              var result = [];
              if (s.length <= 1) {
                return [s];
              } else {
                for (var i = 0; i < s.length; i++) {
                  var c = s[i];
                  var newStr = s.slice(0, i) + s.slice(i + 1, s.length);
                  var l = perm(newStr);
                     
                  for (var j = 0; j < l.length; j++) {
                    var tmp = c + l[j];
                    result.push(tmp);
                  }
                }
              }
              return result;
            };

          數(shù)組隨機(jī)排序

          // 方法1
              function method1(arr){
                  for(var i=0,len=arr.length;i<len;i++){
                      var a=parseInt(Math.random()*len);
                      var temp=arr[a];
                      arr[a]=arr[i];
                      arr[i]=temp;
                  }
                  return arr;
              }
              // 方法2
              function method2(arr){
                  var newarr=[];
                  while(arr.length>0){
                      var len=parseInt(Math.random()*arr.length);
                      newarr.push(arr[len]);
                      arr.splice(len,1)  //splice(index,num,x,x)函數(shù),index刪除元素的位置(必須),num刪除的個(gè)數(shù)(必須),x向數(shù)組添加的新元素(可選)。該函數(shù)返回被刪除元素組成的新數(shù)組,同時(shí)原始數(shù)組也被改變;
                  }
                  return newarr;
              }
              // 方法3
              function method3(arr){
                  arr.sort(function(){
                      return Math.random()-0.5;
                  });
                  console.log(arr);
              }

          題目1

          [
          123 ],
          456 ],
          789 ]
          ]
          輸出: [1,2,4,7,5,3,6,8,9]

          // 對(duì)角線遍歷

          var findDiagonalOrder = function(matrix{
            // 遍歷數(shù)組,角標(biāo)之和遞增輸出
            if(matrix.length === 0){
              return []
            }
            let res = []
            let r = 0
            let c = 0
            let col = matrix[0].length
            let row = matrix.length
            
            for (let i = 0; i < col * row; i ++) {
              //偶數(shù)向上遍歷
              res[i] = matrix[r][c]
              if((r + c) % 2 === 0) {
                if (c === col -1) { // 當(dāng)遍歷到左后一列時(shí),本次遍歷結(jié)束,下移一行為下次遍歷做準(zhǔn)備
                  
                  r++
                } else if (r === 0) { // 當(dāng)遍歷到第一行時(shí),本次遍歷結(jié)束,向右移動(dòng)一格為下次遍歷做準(zhǔn)備
                  // 往移動(dòng)一格準(zhǔn)備向下遍歷
                  c++
                } else { // 一般向上對(duì)角線遍歷
                  r--
                  c++
                }
              } else { // 奇數(shù)向下遍歷
                if (r === row - 1){ // 向下遍歷到最后一行時(shí)本次遍歷結(jié)束,向右移動(dòng)一格,為下一行遍歷做準(zhǔn)備
                  c++
                } else if (c === 0) { // 當(dāng)向下遍歷到第一列時(shí)本次遍歷結(jié)束,向下移動(dòng)一行為下一行遍歷做準(zhǔn)備
                  r++
                } else { // 一般向下對(duì)角線遍歷
                  r++
                  c--
                }
              }
            }

            return res
          };

          題目2

          給定有序數(shù)組[1,2,3,4,6,8,9,10] 輸出連續(xù)的值 結(jié)果為 ['1-4',6,'8-10']

            function merge(arr{
              let start = 0 
              let res = []
              arr.reduce((prev,cur,index) => {
                if (cur - prev !== 1) {
                    let v = index - start > 1 ? `${ arr[start] }-${ arr[index - 1] }` : arr[index - 1
                    res.push(v)
                    start = index
                }
                return cur
            },0)
            // 余下的數(shù)字就都是連續(xù)的了
            if (start < arr.length - 1) res.push(`${arr[start]}-${arr[arr.length -1]}`)
            else if (start === arr.length -1) res.push(arr[arr.length - 1])
            return res
          }


          來源:https://mp.weixin.qq.com/s/JRv4QxgIJX9Uny8pnACgrA


          • 回復(fù)資料包領(lǐng)取我整理的進(jìn)階資料包
          • 回復(fù)加群,加入前端進(jìn)階群
          • console.log("點(diǎn)贊===點(diǎn)看===你我都快樂"
          • Bug離我更遠(yuǎn)了,快樂離我更近了
          瀏覽 51
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美精品一卡二卡 | 99精品在线观看免费 | 久久 无码 一区二区三区四区 | 欧洲成人黄色 | 大香蕉狠狠撸手机免费看视频 |