前端高頻面試題2:JavaScript/TypeScript

1.什么是類數組對象

????????一個擁有 length 屬性和若干索引屬性的對象就可以被稱為類數組對象,類數組對象和數組類似,但是不能調用數組的方法。常見的類數組對象有 arguments 和 DOM 方法的返回結果,還有一個函數也可以被看作是類數組對象,因為它含有 length 屬性值,代表可接收的參數個數。

常見的類數組轉換為數組的方法有這樣幾種:

(1)通過 call 調用數組的 slice 方法來實現轉換

Array.prototype.slice.call(arrayLike);

(2)通過 call 調用數組的 splice 方法來實現轉換

Array.prototype.splice.call(arrayLike, 0);

(3)通過 apply 調用數組的 concat 方法來實現轉換

Array.prototype.concat.apply([], arrayLike);

(4)通過 Array.from 方法來實現轉換

Array.from(arrayLike);

2.Js有哪些基本數據類型

  • 簡單類型

    • Number

    • String

    • Boolean

    • Symbol

    • Null

    • Undefined

  • 復雜數據類型

    • Object

    • Array

    • Function

    • Map

    • Set

3.Js判斷類型的幾種方式,有什么區別

方法支持類型跨框架可靠性原始類型引用類型細分特殊說明
typeof原始類型、函數可靠???null 返回 "object"
instanceof引用類型不可靠???依賴原型鏈
Object.prototype.toString所有類型可靠????最全面

1.typeof

作用:返回變量的原始類型(字符串形式)。 語法:typeof variable 返回值:

  • "undefined"(未定義)

  • "boolean"(布爾值)

  • "string"(字符串)

  • "number"(數字)

  • "bigint"(BigInt類型)

  • "symbol"(Symbol類型)

  • "function"(函數)

  • "object"(對象、數組、null等)

  • "object"(未識別的ES6+類型,如MapSet

特點:

  • 對原始類型(除 null)有效,但對引用類型無法細分(如數組、對象、null 均返回 "object")。

  • typeof null === "object"(歷史遺留問題)。

  • 無法區分對象的具體類型(如 DateRegExp)。

適用場景:快速判斷原始類型或函數。

2.instanceof

作用:檢測變量是否為某個構造函數的實例(基于原型鏈)。 語法:variable instanceof Constructor 返回值:truefalse

特點:

  • 適合判斷引用類型(如數組、自定義類)。

  • 無法判斷原始類型(如 1 instanceof Numberfalse,除非用 new Number(1) 創建)。

  • 跨框架/窗口(iframe)時會失效,因為不同全局環境下的構造函數不共享原型。

  • 若原型鏈被修改,結果可能不準確。

3.Object.prototype.toString.call()

作用:返回變量的內部 [[Class]] 類型標識。 語法:Object.prototype.toString.call(variable) 返回值:形如 "[object Type]" 的字符串,如 "[object Array]""[object Null]"

特點:

  • 最全面的類型判斷方法,支持所有內置類型(包括 nullundefined)。

  • 可通過 Symbol.toStringTag 自定義類型標簽(ES6+),但大部分內置對象不受影響。

  • 對原始類型和引用類型均有效。

適用場景:需要精確判斷所有類型(包括ES6+新增類型)。

4. Js的事件循環(Event Loop)是什么

????????Js是一種單線程語言(HTML5提供了Web Worker可以開啟子線程),同步代碼直接交由Js引擎執行,異步代碼則交由瀏覽器或Node.js執行。

? ? ? ? 關鍵概念:

  1. 調用棧(Call Stack)??:用于跟蹤當前正在執行的函數(執行上下文)。當函數被調用時,它被壓入棧;當函數返回時,它被彈出棧。
  2. ??任務隊列(Task Queue)??:也稱為宏任務隊列(Macro Task Queue),包括 setTimeout、setInterval、I/O、事件回調等。
  3. ??微任務隊列(Micro Task Queue)??:包括 Promise 的回調(then/catch/finally)、MutationObserver、queueMicrotask 等。微任務在當前宏任務結束后立即執行,且會清空整個微任務隊列,直到隊列為空。
  4. ??渲染(Render)步驟??:在事件循環中,可能會在宏任務和微任務之間進行頁面渲染(UI 更新),但這不是事件循環規范的一部分,而是瀏覽器行為

? ? ? ? 事件循環執行過程:

  1. 首先依次執行調用棧中的全部同步代碼
  2. 處理微任務:
    • 調用棧清空后會執行全部微任務
    • 微任務執行期間加入的微任務也會順次執行
  3. 渲染更新(瀏覽器行為與Js事件循環無關)
  4. 執行一個宏任務
  5. 重復循環

? ? ? ? 常見的宏任務與微任務

  • 宏任務
    • setTimeout/setInterval
    • I/O操作
    • 瀏覽器渲染
    • 事件回調(click等事件)
    • 腳本執行(不同的script標簽)
  • 微任務
    • Promise相關方法(Promise.then等)
    • MutationObserver(Dom變化監視)

5.下面代碼的輸出順序是什么(事件循環)

async function async1() {console.log('async1 start');await async2(); // 后續為微任務console.log('async1 end');
}async function async2() {console.log('async2');
}console.log('script start');setTimeout(function() {console.log('setTimeout');
}, 0) // 宏任務async1();new Promise(function(resolve) {console.log('promise1');resolve();
}).then(function() { // 微任務console.log('promise2');
});console.log('script end');
// 順序如下
script start // 第一個同步任務
async1 start // async1方法中的第一個同步任務
async2 // await修飾的方法立即執行,輸出async2,async1方法進入微任務隊列
promise1 // 執行new Promise,輸出promise1,并進入微任務隊列
script end // 執行同步代碼
async1 end // 執行微任務隊列中的第一個任務
promise2 // 執行微任務隊列的第二個任務
setTimeout // 執行宏任務

6.Js原生如何獲取cookie

document.cookie // 結果是一個Json字符串,可使用JSON.parse()轉換

7.Promise.all/allSettled/any/race的區別

Promise.all

  • 核心:等待所有 Promise 全部完成(fulfilled),或遇到第一個失敗(rejected)。

  • 結果:

    • 全部成功時:返回一個數組,元素為每個 Promise 的成功值(順序與輸入一致)。

    • 遇到失敗時:立即拒絕(reject),返回第一個失敗的 Promise 的原因。

  • 適用場景:多個異步操作強依賴,需要所有結果都成功(如:并發請求多個接口)。

  • 示例:

Promise.all([promise1, promise2]) .then(values => console.log(values)) // 所有成功:[value1, value2].catch(error => console.log(error)); // 任一失敗(返回第一個錯誤)

Promise.allSettled

  • 核心:等待所有 Promise 全部完成(無論成功或失敗)。

  • 結果:永遠成功(resolve),返回一個數組,每個元素為對象:

    • { status: "fulfilled", value: <result> }(成功)

    • { status: "rejected", reason: <error> }(失敗)

  • 適用場景:需知道每個操作的最終狀態(無論成功失敗)(如:批量操作后匯總結果)。

  • 示例:

Promise.allSettled([promise1, promise2]).then(results => { results.forEach(result => { if (result.status === "fulfilled") console.log(result.value); else console.error(result.reason); }); });

Promise.any

  • 核心:等待第一個 成功(fulfilled)的 Promise,或所有都失敗。

  • 結果:

    • 任一成功時:返回第一個成功的值。

    • 全部失敗時:拒絕(reject)并拋出 AggregateError,包含所有錯誤信息。

  • 適用場景:獲取最快成功的操作(如:多服務器請求,取最快響應)。

  • 示例:

Promise.any([promise1, promise2]).then(value => console.log(value)) // 第一個成功的值.catch(errors => console.log(errors)); // 所有失敗(AggregateError 包含錯誤數組)

Promise.race

  • 核心:等待第一個 完成(無論成功或失敗)的 Promise。

  • 結果:返回第一個完成的 Promise 的結果(可能是成功值或失敗原因)。

  • 適用場景:競速場景(如:請求超時控制)。

  • 示例:

// 實現超時控制 
const timeout = new Promise((_, reject) =>setTimeout(() => reject("Timeout"), 1000) 
); 
Promise.race([fetchData(), timeout]).then(data => console.log(data)) // 在超時前完成.catch(error => console.log(error)); // 超時或請求失敗

對比表格

方法行為描述成功條件失敗條件返回值類型
??Promise.all??所有成功或任一失敗(短路)全部成功第一個失敗數組(成功值)
??Promise.allSettled??等待所有完成(無論成敗)永不失敗-對象數組(包含狀態和值/原因)
??Promise.any??等待第一個成功或所有失敗第一個成功全部失敗第一個成功的值
??Promise.race??等待第一個完成(無論成敗)第一個完成的結果是成功第一個完成的結果是失敗第一個完成的結果

關鍵區別

  • all vs allSettledall 會在遇到失敗時立即終止,而 allSettled 始終等待所有結果。

  • any vs raceany 只關心第一個成功(忽略失敗),race 關心第一個完成(無論成敗)。

  • 錯誤處理: any 在所有失敗時返回 AggregateError;其他方法直接返回單條錯誤原因。

根據實際需求選擇合適的方法:需要全部成功用 all,容忍失敗用 allSettled,取最快成功用 any,競速場景用 race

?8.原型對象、構造函數、實例之間的關系

對象指向關系屬性/方法
??構造函數??prototype → 原型對象Person.prototype
??原型對象??constructor → 構造函數Person.prototype.constructor
??實例??__proto__ → 原型對象person.__proto__

9.Proxy和Object.defineProperty的區別?

  • Object.defineProperty: 只能對已存在的屬性進行劫持,無法攔截新增的屬性和刪除的屬性(需要通過Vue.setVue.delete實現響應式),由于劫持基于屬性級別,對于大規模對象或者數組來說會導致性能下降;(Vue2響應式的實現方法)

  • Proxy: 劫持整個對象,并返回一個代理對象,提高了初始化性能,同時可以攔截新增屬性和刪除屬性。(Vue3響應式的實現方法)

10.使用Proxy代理一個對象,是對這個對象所有層級進行了劫持嗎

????????不會,proxy只代理外層對象,內層對象需要單獨proxy代理

?11.簡單數組去重的方法

  • 使用Set只運行存儲唯一值的特點
const arr = [1, 2, 2, 3, 3, 4, 5, 5, 6]
const uniqueArr = [...new Set(arr)] 
// 或 const uniqueArr = Array.from(new Set(arr))
  • 使用includes方法檢查新數值中是否存在該元素

const arr = [1, 2, 2, 3, 3, 4, 5, 5, 6] 
const uniqueArr = [] 
arr.forEach(val => { if(!uniqueArr.includes(val)) { uniqueArr.push(val) } 
}
  • 使用indexOf方法,檢查新數組中是否存在該元素

const arr = [1, 2, 2, 3, 3, 4, 5, 5, 6]
const uniqueArr = [] 
arr.forEach(val => { if(uniqueArr.indexOf(val) === -1) { uniqueArr.push(val) } 
}
  • 使用filter方法過濾第一次出現的元素

const arr = [1, 2, 2, 3, 3, 4, 5, 5, 6]
const uniqueArr = arr.filter((val, index, self) => self.indexOf(val) === index
}
  • 使用reduce方法遍歷數組元素

const arr = [1, 2, 2, 3, 3, 4, 5, 5, 6]
const uniqueArr = arr.reduce((res, current) => {if(!res.includes(current) {res.push(current) } return res 
}, [])

12.對象數組如何去重

  • id(或其他鍵相同算為重復)

    • 使用Map

function uniqueById(arr) { return [ ...new Map( arr.map(item => [item.id, item]) ).values() ]; 
} // 使用示例 
const users = [ { id: 1, name: 'John' },{ id: 2, name: 'Jane' }, { id: 1, name: 'Johnny' }, // 相同id { id: 3, name: 'Alice' } 
]; 
console.log(uniqueById(users)); 
// [ 
// { id: 1, name: 'Johnny' }, 
// { id: 2, name: 'Jane' }, 
// { id: 3, name: 'Alice' } 
// ]
  • 使用filter+緩存?
function uniqueById(arr) { const seen = new Set(); return arr.filter(item => { const duplicate = seen.has(item.id); seen.add(item.id);     return !duplicate; }); 
}
  • ?使用reduce?
function uniqueById(arr) { return Object.values(arr.reduce((acc, item) => { acc[item.id] = item; return acc; }, {}) ); 
}
  • 完全相同算重復
    • 使用JSON.stringify(簡單對象)
      
function deepUnique(arr) { const seen = new Set(); return arr.filter(item => { const serialized = JSON.stringify(item); return seen.has(serialized) ? false : seen.add(serialized); }); 
} 
// 使用示例 
const items = [ { id: 1, name: 'Apple' }, { id: 2, name: 'Banana' }, { id: 1, name: 'Apple' }, // 相同對象 { id: 1, name: 'apple' } // 不同對象 
]; 
console.log(deepUnique(items)); 
// [ 
// { id: 1, name: 'Apple' }, 
// { id: 2, name: 'Banana' }, 
// { id: 1, name: 'apple' } 
// ]
  • ?Lodash的isEqual方法(復雜對象推薦)? ? ? ? ? ? ? ? ?
// 需要安裝lodash:npm install lodash 
import _ from 'lodash'; 
function deepUnique(arr) { return arr.reduce((acc, item) => { const isDuplicate = acc.some(accItem => _.isEqual(accItem, item)); return isDuplicate ? acc : [...acc, item]; }, []); 
}

創建于2025.6.2,后續繼續更新

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907911.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907911.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907911.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Security入門:創建第一個安全REST端點項目

項目初始化與基礎配置 創建基礎Spring Boot項目 我們首先創建一個名為ssia-ch2-ex1的空項目(該名稱與配套源碼中的示例項目保持一致)。項目需要添加以下兩個核心依賴: org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-secur…

秋招Day12 - 計算機網絡 - UDP

說說TCP和UDP的區別&#xff1f; TCP使用無邊界的字節流傳輸&#xff0c;可能發生拆包和粘包&#xff0c;接收方并不知道數據邊界&#xff1b;UDP采用數據報傳輸&#xff0c;數據報之間相互獨立&#xff0c;有邊界。 應用場景方面&#xff0c;TCP適合對數據的可靠性要求高于速…

【QQ音樂】sign簽名| data參數加密 | AES-GCM加密 | webpack (下)

1.目標 網址&#xff1a;https://y.qq.com/n/ryqq/toplist/26 我們知道了 sign P(n.data)&#xff0c;其中n.data是明文的請求參數 2.webpack生成data加密參數 那么 L(n.data)就是密文的請求參數。返回一個Promise {<pending>}&#xff0c;所以L(n.data) 是一個異步函數…

Codeforces Round 1028 (Div. 2)(A-D)

題面鏈接&#xff1a;Dashboard - Codeforces Round 1028 (Div. 2) - Codeforces A. Gellyfish and Tricolor Pansy 思路 要知道騎士如果沒了那么這個人就失去了攻擊手段&#xff0c;貪心的來說我們只需要攻擊血量少的即可&#xff0c;那么取min比較一下即可 代碼 void so…

【存儲基礎】存儲設備和服務器的關系和區別

文章目錄 1. 存儲設備和服務器的區別2. 客戶端訪問數據路徑場景1&#xff1a;經過服務器處理場景2&#xff1a;客戶端直連 3. 服務器作為"中轉站"的作用 剛開始接觸存儲的時候&#xff0c;以為數據都是存放在服務器上的&#xff0c;服務器和存儲設備是一個東西&#…

macOS 安裝 Grafana + Prometheus + Node Exporter

macOS 安裝指南&#xff1a;Grafana Prometheus Node Exporter 目錄簡介&#x1f680; 快速開始 安裝 Homebrew1. 安裝 Homebrew2. 更新 Homebrew 安裝 Node Exporter使用 Homebrew 安裝驗證 Node Exporter 安裝 Prometheus使用 Homebrew 安裝驗證安裝 安裝 Grafana使用 Home…

不可變集合類型轉換異常

記錄一個異常&#xff1a;class java.util.ImmutableCollections$ListN cannot be cast to class java.util.ArrayList (java.util.ImmutableCollections$ListN and java.util.ArrayList 文章目錄 1、原因2、解決方式一3、解決方式二4、關于不可變集合的補充4.1 JDK8和9的對比4…

【DAY37】早停策略和模型權重的保存

內容來自浙大疏錦行python打卡訓練營 浙大疏錦行 知識點&#xff1a; 過擬合的判斷&#xff1a;測試集和訓練集同步打印指標模型的保存和加載 僅保存權重保存權重和模型保存全部信息checkpoint&#xff0c;還包含訓練狀態 早停策略 作業&#xff1a; 對信貸數據集訓練后保存權…

【Zephyr 系列 3】多線程與調度機制:讓你的 MCU 同時干多件事

好的,下面是Zephyr 系列第 3 篇:聚焦 多線程與調度機制的實踐應用,繼續面向你這樣的 Ubuntu + 真板實戰開發者,代碼清晰、講解通俗、結構規范,符合 CSDN 高質量博客標準。 ??關鍵詞:Zephyr、線程調度、k_thread、k_sleep、RTOS、BluePill ??適合人群:想從裸機開發進…

實現RabbitMQ多節點集群搭建

目錄 引言 一、環境準備 二、利用虛擬機搭建 ? 三、鏡像集群配置 四、HAProxy實現負載均衡(主用虛擬機操作) 五、測試RabbitMQ集群搭建情況 引言 在現代分布式系統中&#xff0c;消息隊列&#xff08;Message Queue&#xff09;扮演著至關重要的角色,而 RabbitMQ 作為…

異步上傳石墨文件進度條前端展示記錄(采用Redis中String數據結構實現-蘇東坡版本)

昔者&#xff0c;有客臨門&#xff0c;亟需自石墨文庫中擷取卷帙若干。此等文冊&#xff0c;非止一卷&#xff0c;乃累牘連篇&#xff0c;亟需批量轉置。然吾輩慮及用戶體驗&#xff0c;當效東坡"腹有詩書氣自華"之雅意&#xff0c;使操作如行云流水&#xff0c;遂定…

Axure 基礎入門

目錄 認識產品經理 項目團隊* 基本概述 認識產品經理 A公司產品經理 B公司產品經理 C公司產品經理 D公司產品經理 產品經理工作范圍 產品經理工作流程* 產品經理的職責 產品經理的分類 產品經理能力要求 產品工具 產品體驗報告 原型設計介紹 原型設計概述 為…

零基礎學習計算機網絡編程----socket實現UDP協議

本章將會詳細的介紹如何使用 socket 實現 UDP 協議的傳送數據。有了前面基礎知識的鋪墊。對于本章的理解將會變得簡單。將會從基礎的 Serve 的初始化&#xff0c;進階到 Client 的初始化&#xff0c;以及 run。最后實現一個簡陋的小型的網絡聊天室。 目錄 1.UdpSever.h 1.1 構造…

普中STM32F103ZET6開發攻略(二)

接上文&#xff1a;普中STM32F103ZET6開發攻略&#xff08;一&#xff09;-CSDN博客 各位看官老爺們&#xff0c;點擊關注不迷路喲。你的點贊、收藏&#xff0c;一鍵三連&#xff0c;是我持續更新的動力喲&#xff01;&#xff01;&#xff01; 目錄 接上文&#xff1a;普中…

用提示詞寫程序(3),VSCODE+Claude3.5+deepseek開發edge擴展插件V2

edge擴展插件;篩選書簽,跳轉搜索,設置背景 鏈接: https://pan.baidu.com/s/1nfnwQXCkePRnRh5ltFyfag?pwd86se 提取碼: 86se 導入解壓的擴展文件夾: 導入擴展成功: edge擴展插件;篩選書簽,跳轉搜索,設置背景

電腦桌面便簽軟件哪個好?桌面好用便簽備忘錄推薦

在日常辦公中&#xff0c;一款優秀的桌面便簽工具能顯著提升工作效率。面對市面上琳瑯滿目的選擇&#xff0c;不少用戶都難以抉擇。如果你正在尋找一款兼具輕量化與多功能性的便簽軟件&#xff0c;那么集實用性與便捷性于一身的"好用便簽"&#xff0c;或許就是你的理…

性能優化 - 工具篇:基準測試 JMH

文章目錄 Pre引言1. JMH 簡介2. JMH 執行流程詳解3. 關鍵注解詳解3.1 Warmup3.2 Measurement3.3 BenchmarkMode3.4 OutputTimeUnit3.5 Fork3.6 Threads3.7 Group 與 GroupThreads3.8 State3.9 Setup 與 TearDown3.10 Param3.11 CompilerControl 4. 示例代碼與分析4.1 關鍵點解讀…

2025年十大AI幻燈片工具深度評測與推薦

我來告訴你一個好消息。 我們已經親自測試和對比了市面上最優秀的AI幻燈片工具&#xff0c;讓你無需再為選擇而煩惱。 得益于AI技術的飛速發展&#xff0c;如今你可以快速制作出美觀、專業的幻燈片。 這些智能平臺的功能遠不止于配色美化——它們能幫你頭腦風暴、梳理思路、…

雪花算法:分布式ID生成的優雅解決方案

一、雪花算法的核心機制與設計思想 雪花算法&#xff08;Snowflake&#xff09;是由Twitter開源的分布式ID生成算法&#xff0c;它通過巧妙的位運算設計&#xff0c;能夠在分布式系統中快速生成全局唯一且趨勢遞增的ID。 1. 基本結構 雪花算法生成的是一個64位&#xff08;lo…

第1章:走進Golang

第1章&#xff1a;走進Golang 一、Golang簡介 Go語言&#xff08;又稱Golang&#xff09;是由Google的Robert Griesemer、Rob Pike及Ken Thompson開發的一種開源編程語言。它誕生于2007年&#xff0c;2009年11月正式開源。Go語言的設計初衷是為了在不損失應用程序性能的情況下…