中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

一些前端基礎知識整理

發布時間:2021-10-18 14:14:23 來源:億速云 閱讀:121 作者:iii 欄目:web開發

這篇文章主要講解了“一些前端基礎知識整理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“一些前端基礎知識整理”吧!

Call, bind, apply實現

// call Function.prototype.myCall = function (context) {   context = context ? Object(context) : window    context.fn = this;    let args = [...arguments].slice(1);   const result = context.fn(...args);   delete context.fn;   return result; }  // apply Function.prototype.myApply = function (context) {   context = context ? Object(context) : window;   context.fn = this;    let args = [...arguments][1];   let result;   if (args.length === 0) {       result = context.fn();   } else {       result = context.fn(args);   }   delete context.fn;   return result; }  // bind Function.prototype.myBind = function (context) {   let self = this;   let args = [...arguments].slice(1);    return function() {     let newArgs = [...arguments];     return self.apply(context, args.concat(newArgs));   } }

原型與原型鏈

每一個JavaScript對象(null除外)在創建的時候會關聯另一個對象,這個被關聯的對象就是原型。每一個JavaScript對象(除了  null)都具有的__proto__屬性會指向該對象的原型。JavaScript中所有的對象都是由它的原型對象繼承而來,而原型也是一個對象,它也有自己的原型對象,這樣層層上溯,就形成了一個類似鏈表的結構,這就是原型鏈。每一個對象都會從原型"繼承"屬性。

實例對象和構造函數都可以指向原型, 原型可以指向構造函數,不能指向實例(因為可以有多個實例)。

原型對象有兩個屬性,constructor 和 __proto__。

function Person() {} var person = new Person();  // 實例原型 === 構造函數原型 person.__proto__ === Person.prototype // true // 原型構造函數 === 構造函數 Person.prototype.constructor === Person // true

react diff

  • React 通過制定大膽的 diff 策略,將 O(n3) 復雜度的問題轉換成 O(n) 復雜度的問題;

  • React 通過分層求異的策略,對 tree diff 進行算法優化;

  • 對樹進行分層比較,兩棵樹只會對同一層次的節點進行比較。

  • React 通過相同類生成相似樹形結構,不同類生成不同樹形結構的策略,對 component diff 進行算法優化;

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 如果是同一類型的組件,按照原策略繼續比較 virtual DOM tree。

  3. 如果不是,則將該組件判斷為 dirty component,從而替換整個組件下的所有子節點。

  4. 對于同一類型的組件,有可能其 Virtual DOM 沒有任何變化,如果能夠確切的知道這點那可以節省大量的 diff 運算時間,因此 React  允許用戶通過 shouldComponentUpdate() 來判斷該組件是否需要進行 diff。

  • React 通過設置唯一 key的策略,對 element diff 進行算法優化;

  • 建議,在開發組件時,保持穩定的 DOM 結構會有助于性能的提升;

遍歷對象

對象遍歷方法總結:

  • for...in:遍歷對象自身, 包含繼承, 可枚舉,不含 Symbol 的屬性。

  • Object.keys(obj):遍歷對象自身, 不含繼承,可枚舉,不含 Symbol 的屬性。【values, entries】

  • Object.getOwnPropertyNames(obj):遍歷對象自身, 不含繼承, 不含 Symbol 的屬性, 不管是否可枚舉

  • Object.getOwnPropertySymbols(obj): 遍歷對象自身, 不含繼承, 所有 Symbol 的屬性, 不管是否可枚舉

  • Reflect.ownKeys(obj): 遍歷對象自身,不含繼承,所有鍵名,不管是否Symbol 和可枚舉。

  • 對象其他方法:

  • JSON.stringify():只串行化對象自身,不含繼承,可枚舉,不含 Symbol屬性。【function,undefined,  Symbol會丟失, set、map會處理成空對象】

  • Object.assign():只拷貝對象自身,不含繼承, 可枚舉屬性, 不管是否是Symbol 。【全部數據類型屬性值】

一些前端基礎知識整理

異步加載腳本

默認情況下,瀏覽器是同步加載 JavaScript 腳本,即渲染引擎遇到<script>標簽就會停下來,等到執行完腳本,再繼續向下渲染。如果是外部腳本,還必須加入腳本下載的時間。

異步加載腳本方法:defer與async。

defer與async的區別是:defer要等到整個頁面在內存中正常渲染結束(DOM 結構完全生成,以及其他腳本執行完成),才會執行;async一旦下載完,渲染引擎就會中斷渲染,執行這個腳本以后,再繼續渲染。一句話,defer是“渲染完再執行”,async是“下載完就執行”。另外,如果有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。

瀏覽器對于帶有type="module"的<script>,都是異步加載,不會造成堵塞瀏覽器,即等到整個頁面渲染完,再執行模塊腳本,等同于打開了<script>標簽的defer屬性。

ES6 模塊與 CommonJS 模塊的差異

  • CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。

  • CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。

  • 因為 CommonJS 加載的是一個對象(即module.exports屬性),該對象只有在腳本運行完才會生成。而 ES6 模塊不是對象,它的對外接口只是一種靜態定義,在代碼靜態解析階段就會生成。

  • CommonJS 模塊的require()是同步加載模塊,ES6 模塊的import命令是異步加載,有一個獨立的模塊依賴的解析階段。

回流Reflow與重繪Repaint
回流:元素的大小或者位置發生了變化,觸發了重新布局,導致渲染樹重新計算布局和渲染。頁面第一次加載的時候,至少發生一次回流。

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 添加或刪除可見的DOM元素;

  3. 元素的位置發生變化;

  4. 元素的尺寸發生變化;

  5. 內容發生變化(比如文本變化或圖片被另一個不同尺寸的圖片所替代);

  6. 頁面一開始渲染的時候(這個無法避免);

  7. 瀏覽器的窗口尺寸變化, 因為回流是根據視口的大小來計算元素的位置和大小的;

重繪:元素的外觀,風格改變,而不會影響布局(不包含寬高、大小、位置等不變)。
如:outline, visibility, color, background-color......等

Reflow 的成本比 Repaint 高得多的多。DOM Tree 里的每個結點都會有 reflow 方法,一個結點的 reflow 很有可能導致子結點,甚至父點以及同級結點的 reflow。。回流一定會觸發重繪,而重繪不一定會回流

減少重繪與回流

1.CSS方法

  • 使用 visibility 替換 display: none ,因為前者只會引起重繪,后者會引發回流

  • 避免使用table布局,可能很小的一個小改動會造成整個 table 的重新布局。

  • 避免設置多層內聯樣式,CSS 選擇符從右往左匹配查找,避免節點層級過多。

  • 將動畫效果應用到position屬性為absolute或fixed的元素上,避免影響其他元素的布局,這樣只是一個重繪,而不是回流,同時,控制動畫速度可以選擇 requestAnimationFrame

  • 避免使用CSS表達式,可能會引發回流。

  • 將頻繁重繪或者回流的節點設置為圖層,圖層能夠阻止該節點的渲染行為影響別的節點,例如will-change、video、iframe等標簽,瀏覽器會自動將該節點變為圖層。

  • CSS3 硬件加速(GPU加速),使用css3硬件加速,可以讓transform、opacity、filters這些動畫不會引起回流重繪 。但是對于動畫的其它屬性,比如background-color這些,還是會引起回流重繪的,不過它還是可以提升這些動畫的性能。

2.JavaScript方法

  • 避免頻繁操作樣式,最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性。

  • 避免頻繁操作DOM,創建一個documentFragment,在它上面應用所有DOM操作,最后再把它添加到文檔中。

  • 避免頻繁讀取會引發回流/重繪的屬性,如果確實需要多次使用,就用一個變量緩存起來。

CSS3硬件加速(GPU加速)

CSS3 硬件加速又叫做 GPU 加速,是利用 GPU 進行渲染,減少 CPU 操作的一種優化方案。

render tree -> 渲染元素 -> 圖層 -> GPU 渲染 -> 瀏覽器復合圖層 -> 生成最終的屏幕圖像。

瀏覽器在獲取 render tree后,渲染樹中包含了大量的渲染元素,每一個渲染元素會被分到一個個圖層中,每個圖層又會被加載到 GPU 形成渲染紋理。GPU 中 transform 是不會觸發 repaint ,最終這些使用 transform 的圖層都會由獨立的合成器進程進行處理。

CSS3觸發硬件加速的屬性:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. transform

  3. opacity

  4. filter

  5. will-change

http請求方法
HTTP1.0定義了三種請求方法:GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. OPTIONS:即預檢請求,可用于檢測服務器允許的http方法。當發起跨域請求時,由于安全原因,觸發一定條件時瀏覽器會在正式請求之前自動先發起OPTIONS請求,即CORS預檢請求,服務器若接受該跨域請求,瀏覽器才繼續發起正式請求。

  3. HEAD: 向服務器索與GET請求相一致的響應,只不過響應體將不會被返回,用于獲取報頭。

  4. GET:向特定的資源發出請求。注意:GET方法不應當被用于產生“副作用”的操作中

  5. POST:向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。

  6. PUT:向指定資源位置上傳其最新內容

  7. DELETE:請求服務器刪除Request-URL所標識的資源

  8. TRACE:回顯服務器收到的請求,主要用于測試或診斷

  9. CONNECT:HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器

js判斷數據類型

1. typeof 操作符

  • 對于基本類型,除 null 以外,均可以返回正確的結果。

  • 對于引用類型,除 function 以外,一律返回 object 類型。

  • 對于 null ,返回 object 類型。

  • 對于 function 返回 function 類型。

2. instanceof

用來判斷 A 是否為 B 的實例,檢測的是原型。instanceof 只能用來判斷兩個對象是否屬于實例關系,  而不能判斷一個對象實例具體屬于哪種類型。

instanceof 主要的實現原理就是只要右邊變量的 prototype 在左邊變量的原型鏈上即可。

3. constructor

  • null 和 undefined 是無效的對象,不會有 constructor 存在的

  • 函數的 constructor 是不穩定的,這個主要體現在自定義對象上,當開發者重寫 prototype 后,原有的 constructor  引用會丟失,constructor 會默認為 Object。為了規范開發,在重寫對象原型時一般都需要重新給 constructor 賦值。

4. toString

toString() 是 Object 的原型方法,調用該方法,默認返回當前對象的 [[Class]] 。這是一個內部屬性,其格式為 [object  Xxx] ,其中 Xxx 就是對象的類型。

 瀏覽器事件模型

DOM事件流(event flow )存在三個階段:事件捕獲階段、處于目標階段、事件冒泡階段。

// useCapture:true, 即采用事件捕獲方式 window.addEventListener("click", function(e){   console.log("window 捕獲"); }, true);  // useCapture:false【默認為false】,即采用事件冒泡方式 window.addEventListener("click", function(e){   console.log("window 冒泡"); }, false);

目標元素(被點擊的元素)綁定的事件都會發生在目標階段,在綁定捕獲代碼之前寫了綁定的冒泡階段的代碼,所以在目標元素上就不會遵守先發生捕獲后發生冒泡這一規則,而是先綁定的事件先發生。

不是目標元素,它上面綁定的事件會遵守先發生捕獲后發生冒泡的規則。

e.stopPropagation():阻止事件傳播。不僅可以阻止事件在冒泡階段的傳播,還能阻止事件在捕獲階段的傳播。

e.preventDefault():  阻止事件的默認行為。默認行為是指:點擊a標簽就轉跳到其他頁面、拖拽一個圖片到瀏覽器會自動打開、點擊表單的提交按鈕會提交表單等

http緩存: 強制緩存和協商緩存

良好的緩存策略可以降低資源的重復加載提高網頁的整體加載速度。

緩存原理

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 瀏覽器在加載資源時,根據請求頭的expires和cache-control判斷是否命中強緩存,是則直接從緩存讀取資源,不會發請求到服務器。

  3. 如果沒有命中強緩存,瀏覽器會發送一個請求到服務器,通過last-modified和etag驗證是否命中協商緩存。當向服務端發起緩存校驗的請求時,服務端會返回  200 ok表示返回正常的結果或者 304 Not  Modified(不返回body)表示瀏覽器可以使用本地緩存文件。304的響應頭也可以同時更新緩存文檔的過期時間

  4. 如果前面兩者都沒有命中,直接從服務器加載資源。

實現方式

強緩存通過Expires和Cache-Control實現。

協商緩存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】這兩對Header來管理的。

Expires

Expires是http1.0提出的一個表示資源過期時間的header,它是一個絕對時間,由服務器返回。Expires  受限于本地時間,如果修改了本地時間,可能會造成緩存失效。

Expires: Wed, 11 May 2018 07:20:00 GMT

Cache-Control

Cache-Control 出現于 HTTP / 1.1,優先級高于 Expires , 表示的是相對時間。

no-store:沒有緩存。緩存中不得存儲任何關于客戶端請求和服務端響應的內容。每次由客戶端發起的請求都會下載完整的響應內容。 no-cache: 緩存但重新驗證。每次有請求發出時,緩存會將此請求發到服務器(譯者注:該請求應該會帶有與本地緩存相關的驗證字段),服務器端會驗證請求中所描述的緩存是否過期,若未過期(返回304),則緩存才使用本地緩存副本。 private:只允許客戶端瀏覽器緩存。 public: 允許所有用戶緩存。例如中間代理、CDN等 max-age=<seconds>:表示資源能夠被緩存的最大時間。相對Expires而言,max-age是距離請求發起的時間的秒數。針對應用中那些不會改變的文件,通常可以手動設置一定的時長以保證緩存有效,例如圖片、css、js等靜態資源。 must-revalidate:觸發緩存驗證。驗證它的狀態,已過期的緩存將不被使用

Last-Modified,If-Modified-Since

Last-Modifie表示本地文件最后修改日期,瀏覽器會在request header加  If-Modified-Since(上次返回的Last-Modified的值),詢問服務器在該日期后資源是否有更新,有更新的話就會將新的資源發送回來。

但是如果在本地打開緩存文件,就會造成 Last-Modified 被修改,所以在 HTTP / 1.1 出現了 ETag。

ETag、If-None-Match

Etag就像一個指紋,資源變化都會導致ETag變化,跟最后修改時間沒有關系,ETag可以保證每一個資源是唯一的。

If-None-Match的header會將上次返回的Etag發送給服務器,詢問該資源的Etag是否有更新,有變動就會發送新的資源回來。

ETag的優先級比Last-Modified更高。

具體為什么要用ETag,主要出于下面幾種情況考慮:

  • 一些文件也許會周期性的更改,但是他的內容并不改變(僅僅改變的修改時間),這個時候我們并不希望客戶端認為這個文件被修改了,而重新GET;

  • 某些文件修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒);

  • 某些服務器不能精確的得到文件的最后修改時間。

防抖和節流

防抖:當你在頻繁調用方法時,并不會執行,只有當你在指定間隔內沒有再調用,才會執行函數。

節流:在一個單位時間內,只能觸發一次函數。如果這個單位時間內觸發多次函數,只有一次生效。

防抖

function debounce(fn, wait) {   let time = null;    return (function() {     const context = this;     const args = arguments;      if (time) {       clearTimeout(time);       time = null;     }     time = setTimeout(() => {       fn.call(context, args);     }, wait);   }); }

節流

function throttle(fn, wait)  {   let lastTime;    return (     function() {       const context = this;       const args = arguments;       let nowTime = + new Date();        if (nowTime > lastTime + wait || !lastTime) {         fn.call(context, args);         lastTime = nowTime;       }     }   );

大小單位區別

px:像素。

em:參考物是父元素的font-size,具有繼承的特點。如果自身定義了font-size按自身來計算,整個頁面內1em不是一個固定的值。

rem:相對于根元素html的font-size計算,不會像em那樣,依賴于父元素的字體大小,而造成混亂。

vw:視窗寬度,1vw等于視窗寬度的1%。

vh:視窗高度,1vh等于視窗高度的1%。

vm:min(vw, vh)。

%:是相對于父元素的大小設定的比率,position:absolute;的元素是相對于已經定位的父元素,position:fixed;的元素是相對可視窗口。

  • 瀏覽器默認字體是16px, body設置font-size:62.5%, 那么1rem =62.5% * 16=10px 。

  • 谷歌瀏覽器強制最小字體為12號,即使設置成 10px 最終都會顯示成  12px,當把html的font-size設置成10px,子節點rem的計算還是以12px為基準。

Box-sizing

  • content-box:這是默認情況,整個元素的高度和寬度就是元素內容

  • border-box:這種情況下,你設置的width和height屬性值就是針對整個元素,包括了border,padding,和元素內容。

函數聲明和函數表達式

// 函數聲明 function wscat(type){   return 'wscat'; }  // 函數表達式 var oaoafly = function(type){   return "oaoafly"; }
  • JavaScript  解釋器中存在一種變量聲明被提升的機制,也就是說函數聲明會被提升到作用域的最前面,即使寫代碼的時候是寫在最后面,也還是會被提升至最前面。

  • 用函數表達式創建的函數是在運行時進行賦值,且要等到表達式賦值完成后才能調用

函數聲明在JS解析時進行函數提升,因此在同一個作用域內,不管函數聲明在哪里定義,該函數都可以進行調用。而函數表達式的值是在JS運行時確定,并且在表達式賦值完成后,該函數才能調用。這個微小的區別,可能會導致JS代碼出現意想不到的bug,讓你陷入莫名的陷阱中。

事件循環EventLoop

JavaScript是一個單線程的腳本語言。

所有同步任務都在主線程上執行,形成一個執行棧 (Execution Context Stack);而異步任務會被放置到 Task  Table(異步處理模塊),當異步任務有了運行結果,就將注冊的回調函數移入任務隊列(兩種隊列)。

一旦執行棧中的所有同步任務執行完畢,引擎就會讀取任務隊列,然后將任務隊列中的第一個任務取出放到執行棧中運行。(所有會進入的異步都是指的事件回調中的那部分代碼)

只要主線程空了,就會去讀取任務隊列,該過程不斷重復,這就是所謂的 事件循環。

宏任務和微任務

宏任務會進入一個隊列,微任務會進入到另一個隊列,且微任務要優于宏任務執行。

宏任務:script(整體代碼)、setTimeout、setInterval、I/O、事件、postMessage、  MessageChannel、setImmediate (Node.js)

微任務:Promise.then、 MutaionObserver、process.nextTick (Node.js)

宏任務會進入一個隊列,而微任務會進入到另一個不同的隊列,且微任務要優于宏任務執行。

Promise

1. Promise.all: 全部fulfilled,  才進入then, 否則 catch 2. Promise.race: 任一個返回,不管是fulfilled還是rejected,  進入相應的then/catch 3. Promise.allSettled: 全部返回,不管是fulfilled還是rejected,  進入then 4. Promise.any: 任一個返回fulfilled,  就進入then, 否則 catch

虛擬dom原理

Virtual DOM是對DOM的抽象,本質上是JavaScript對象,這個對象就是更加輕量級的對DOM的描述.

箭頭函數與普通函數區別

  • 語法更加簡潔、清晰

  • 不綁定this,會捕獲其所在的上下文的this值,作為自己的this值

  • 箭頭函數繼承而來的this指向永遠不變

  • .call()/.apply()/.bind()無法改變箭頭函數中this的指向

  • 不能作為構造函數使用, 因為沒有自己的 this,無法調用 call,apply;沒有 prototype 屬性 ,而 new  命令在執行時需要將構造函數的 prototype 賦值給新的對象的__prpto__ 。

  • 沒有自己的arguments,在箭頭函數中訪問arguments實際上獲得的是外層局部(函數)執行環境中的值。如果要用,可以用 rest  參數代替。

  • 沒有原型prototype, 指向 undefined

  • 不能使用yeild關鍵字

new

new 關鍵字會進行如下的操作:

  1. 鴻蒙官方戰略合作共建——HarmonyOS技術社區

  2. 創建一個空的簡單JavaScript對象(即{});

  3. 鏈接該對象(設置該對象的__proto__)到構造器函數的原型 ;

  4. 將新創建的對象作為this的上下文 ;

  5. 返回。如果該函數沒有返回對象,則返回this。

function newFunc(father, ...rest) {   // 首先創建一個空對象   var result = {};   // 將空對象的原型賦值為構造器函數的原型   result.__proto__ = father.prototype;   // 更改構造器函數內部this,將其指向新創建的空對象   var result2 = father.apply(result, rest);    if ((typeof result2 === 'object' || typeof result2 === 'function') && result2 !== null) {     return result2;   }   return result; }

水平與垂直居中實現方式

水平居中

  • text-align: center; 行內元素適用

  • margin: 0 auto; 適用塊級元素

  • width: fit-content; 若子元素包含 float:left 屬性, 為了讓子元素水平居中, 則可讓父元素寬度設置為fit-content,  并且配合margin。

.parent {   width:fit-content;   margin:0 auto; }

flex

.parent {   display: flex;   justify-content: center; }

盒模型, 使用flex 2009年版本

.parent {   display: box;   box-orient: horizontal;   box-pack: center; }

transform

.son {   position: absolute;   left: 50%;   transform: translate(-50%, 0); }

兩種不同的絕對定位方法

.son {   position: absolute;   width: 固定;   left: 50%;   margin-left: -0.5 * 寬度; }  .son {   position: absolute;   width: 固定;   left: 0;   right: 0;   margin: 0 auto; }

垂直居中

  • 單行文本, line-height

  • 行內塊級元素, 使用 display: inline-block, vertical-align: middle; 加上偽元素輔助實現

.parent::after, .son {     display:inline-block;     vertical-align:middle; } .parent::after {     content:'';     height:100%; }
  •  vertical-align。vertical-align只有在父層為 td 或者 th 時, 才會生效, 對于其他塊級元素, 例如 div、p 等,  默認情況是不支持的. 為了使用vertical-align, 我們需要設置父元素display:table, 子元素  display:table-cell;vertical-align:middle;

flex

.parent {   display: flex;   align-items: center; }

盒模型

.parent {   display: box;   box-orient: vertical;   box-pack: center; }

transform

.son {   position: absolute;   top: 50%;   transform: translate(0, -50%); }

兩種不同的絕對定位方法

.son {   position: absolute;   height: 固定;   top: 50%;   margin-top: -0.5 * height; }  .son {   position: absolute;   height: 固定;   top: 0;   bottom: 0;   margin: auto 0; }

flex, 盒模型, transform, 絕對定位, 這幾種方法同時適用于水平居中和垂直居中

排序

冒泡排序

function bubbleSort(arr) {   const len = arr.length;   for (let i = 0; i < len - 1; i++) {     for (let j = i + 1; j < len; j++) {       if (arr[j] < arr[i]) {         [arr[j], arr[i]] = [arr[i], arr[j]];       }     }   }   return arr; }

選擇排序

選擇排序(Selection-sort)是一種簡單直觀的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

function selectionSort(arr) {   const len = arr.length;   for (let i = 0; i < len - 1; i++) {     let index = i;     for (let j = i + 1; j < len; j++) {       if (arr[j] < arr[index]) {         index = j;       }     }     if (index !== i) {       [arr[i], arr[index]] = [arr[index], arr[i]];     }   }   return arr; }

插入排序

插入排序(Insertion-Sort)的算法描述是一種簡單直觀的排序算法。它的工作原理是通過構建有序序列,對于未排序數據,在已排序序列中從后向前掃描,找到相應位置并插入。

插入排序在實現上,通常采用in-place排序(即只需用到O(1)的額外空間的排序),因而在從后向前掃描過程中,需要反復把已排序元素逐步向后挪位,為最新元素提供插入空間。

function insertionSort(arr) {   const len = arr.length;   for (let i = 1; i < len; i++) {     let j = i - 1;     const value = arr[i];     while (arr[j] > value && j >= 0) {       arr[j + 1] = arr[j];       j--;     }     arr[j + 1] = value;   }   return arr; }

歸并排序

歸并排序是建立在歸并操作上的一種有效的排序算法。該算法是采用分治法(Divide and  Conquer)的一個非常典型的應用。歸并排序是一種穩定的排序方法。先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為2-路歸并。

function mergeSort(arr) {  //采用自上而下的遞歸方法   var len = arr.length;   if (len < 2) return arr;    const middle = Math.floor(len / 2);   let left = arr.slice(0, middle);   let right = arr.slice(middle);   return merge(mergeSort(left), mergeSort(right)); }  function merge(left, right) {   let result = [];   while (left.length && right.length) {     if (left[0] <= right[0]) {       result.push(left.shift());     } else {       result.push(right.shift());     }   }   return result.concat(left).concat(right); }

快速排序

快速排序的基本思想:通過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。

function quickSort(arr) {   if (arr.length <= 1) return arr;   const pivotIndex = Math.floor(arr.length / 2);   const pivot = arr.splice(pivotIndex, 1)[0];   let left = [];   let right = [];   for (let i = 0; i < arr.length; i++){     if (arr[i] < pivot) {       left.push(arr[i]);     } else {       right.push(arr[i]);     }   }   return quickSort(left).concat([pivot], quickSort(right)); }; };

洗牌算法

function shuffle(arr){   const length = arr.length;   while (length > 0) {     const random = Math.floor(Math.random() * length);     length--;     [arr[length], arr[random]] = [arr[random], arr[length]];   }   return arr; }  // 或 arr.sort(function(){   return .5 - Math.random(); });

感謝各位的閱讀,以上就是“一些前端基礎知識整理”的內容了,經過本文的學習后,相信大家對一些前端基礎知識整理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

海淀区| 从化市| 阿拉善盟| 昭觉县| 万州区| 舞阳县| 庐江县| 大化| 重庆市| 措美县| 分宜县| 天峻县| 齐河县| 玉树县| 方山县| 常山县| 巩义市| 凤凰县| 眉山市| 景谷| 达拉特旗| 德保县| 沙坪坝区| 安乡县| 万州区| 峨眉山市| 那坡县| 湘潭市| 宁德市| 沁源县| 张家口市| 林周县| 常德市| 新营市| 临洮县| 平顶山市| 汪清县| 康定县| 大连市| 桓仁| 四平市|