前端的面試筆記——JavaScript篇(二)

一、instanceof

在 JavaScript 里,instanceof 是一個相當實用的運算符,它的主要功能是檢查某個對象是否屬于特定構造函數的實例。這里需要明確的是,判斷的依據并非對象的類型,而是其原型鏈。下面為你詳細介紹它的用法和特點:

基礎語法

object instanceof constructor
objectconstructor 的實例,或者說在其原型鏈上能找到 constructor.prototype,該表達式就會返回 true,反之則返回 false

主要作用

1. 判定對象類型

你可以借助 instanceof 來判斷一個對象是否為特定類的實例。

class Person {}
const person = new Person();console.log(person instanceof Person); // true
2. 驗證內置對象類型

對于 JavaScript 的內置對象,同樣可以使用 instanceof 來驗證其類型。

const arr = [];
const num = 5;console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true(因為數組本質上也是對象)
console.log(num instanceof Number); // false(基本類型通過裝箱轉換才會成為對象)
console.log(new Number(5) instanceof Number); // true
3. 檢查原型鏈關系

instanceof 還能用于檢查對象的原型鏈上是否存在某個構造函數的原型。

function Animal() {}
function Dog() {}Dog.prototype = Object.create(Animal.prototype);const dog = new Dog();console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true

需留意的特殊情形

1. 基本類型與 instanceof

基本類型(像 numberstringboolean 等)直接使用 instanceof 會返回 false,除非它們通過構造函數(如 new Number())被轉換為對象。

const str = "hello";
const strObj = new String("hello");console.log(str instanceof String); // false
console.log(strObj instanceof String); // true
2. 跨窗口(Cross-Window)問題

在瀏覽器環境中,不同窗口(比如 iframe)的全局對象是相互獨立的。這就導致,從一個窗口創建的對象和另一個窗口的構造函數使用 instanceof 比較時,結果會是 false

// 在 iframe 中執行
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);const arr = iframe.contentWindow.Array();
console.log(arr instanceof Array); // false(當前窗口的 Array 與 iframe 的 Array 不同)
3. 手動修改原型

要是手動對對象的原型(__proto__Object.setPrototypeOf)進行修改,instanceof 的結果可能會與預期不符。

const obj = {};
Object.setPrototypeOf(obj, Array.prototype);console.log(obj instanceof Array); // true(盡管 obj 并非通過 new Array() 創建)

替代方案

1. Object.prototype.toString.call()

這種方法可以更精準地判斷對象類型,而且能處理基本類型的情況。

const arr = [];
console.log(Object.prototype.toString.call(arr)); // [object Array]
2. Array.isArray()

專門用于判斷一個值是否為數組,并且能解決跨窗口的問題。

console.log(Array.isArray([])); // true

總結

instanceof 運算符在檢查對象與構造函數的繼承關系時非常有用,但在使用過程中要特別注意基本類型、跨窗口對象以及原型修改等特殊情況可能帶來的影響。在實際的編程工作中,你可以根據具體的使用場景,將 instanceof 與其他類型檢查方法結合起來使用。

二、深拷貝和淺拷貝

在 JavaScript 中,深拷貝和淺拷貝是處理對象和數組時的重要概念,也是面試中的高頻考點。以下是對這兩個概念的詳細解釋及相關面試題分析:

一)、基本概念

1. 淺拷貝(Shallow Copy)
  • 定義:創建一個新對象,復制原始對象的一層屬性。如果屬性是基本類型(如 number、string),則復制值;如果屬性是引用類型(如對象、數組),則復制引用(內存地址)。
  • 特點:新對象和原始對象共享引用類型的屬性,修改其中一個會影響另一個。
2. 深拷貝(Deep Copy)
  • 定義:創建一個新對象,遞歸復制原始對象的所有屬性(包括嵌套的引用類型)。
  • 特點:新對象和原始對象完全獨立,修改其中一個不會影響另一個。

二)、實現方式

淺拷貝方法

淺拷貝直接賦值的方式這里就不做講解了,這里列舉一些容易忽略的淺拷貝方式,在項目中可能會因此產生一些bug問題。

1. 手動遍歷對象:
function shallowCopy(obj) {const newObj = {};for (let key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = obj[key];}}return newObj;
}
2. 展開語法(Spread):
const newObj = { ...oldObj };
const newArr = [...oldArr];
3. Object.assign():
const newObj = Object.assign({}, oldObj);
4. Array.prototype.slice() / Array.from():
const newArr = oldArr.slice();
const newArr = Array.from(oldArr);
深拷貝方法
1. JSON.parse(JSON.stringify()):
const newObj = JSON.parse(JSON.stringify(oldObj));
限制
  • 無法處理函數、正則、Date 等特殊對象。
  • 會忽略 undefinedsymbol 類型的屬性。
  • 無法處理循環引用(對象引用自身)。
2. 遞歸實現(手動-推薦方式):
function deepCopy(obj) {if (obj === null || typeof obj !== 'object') return obj;const newObj = Array.isArray(obj) ? [] : {};for (let key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = deepCopy(obj[key]);}}return newObj;
}
3. 第三方庫:
  • Lodash 的 _.cloneDeep()
    const newObj = _.cloneDeep(oldObj);
    
  • 結構化克隆(Structured Clone):
    瀏覽器原生 API,支持循環引用,但有兼容性限制
    const newObj = structuredClone(oldObj); // 瀏覽器原生 API,支持循環引用,但有兼容性限制
    

三)、面試題

1. 手寫深拷貝函數

要求:實現一個能處理嵌套對象、數組、循環引用的深拷貝函數。
答案示例:

function deepCopy(obj, map = new WeakMap()) {// 處理基本類型和 nullif (obj === null || typeof obj !== 'object') return obj;// 處理循環引用if (map.has(obj)) return map.get(obj);// 處理特殊對象(Date、RegExp 等)if (obj instanceof Date) return new Date(obj.getTime());if (obj instanceof RegExp) return new RegExp(obj);// 創建新對象/數組const newObj = Array.isArray(obj) ? [] : {};map.set(obj, newObj); // 記錄已處理的對象// 遞歸復制所有屬性for (let key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = deepCopy(obj[key], map);}}return newObj;
}
2. 淺拷貝和深拷貝的區別

回答要點:

  • 淺拷貝:只復制一層屬性,引用類型共享內存地址。
  • 深拷貝:完全獨立的新對象,遞歸復制所有層級。
  • 使用場景:淺拷貝適用于簡單對象,深拷貝適用于需要完全隔離的復雜對象。
3. JSON.stringify () 的局限性

回答要點:

  • 無法處理函數、正則、Symbol、Date 等特殊對象。
  • 忽略 undefined 和循環引用。
  • 示例:
    const obj = {func: () => {},date: new Date(),nested: { prop: undefined }
    };
    const copy = JSON.parse(JSON.stringify(obj));
    console.log(copy); // { date: "2023-01-01T00:00:00.000Z", nested: {} }
    
4. 如何處理循環引用?

回答要點:

  • 使用 WeakMap 記錄已處理的對象,避免遞歸時無限循環。
  • 示例代碼(見手寫深拷貝函數中的 map 參數)。
5. 實際應用場景
  • 淺拷貝:狀態管理庫(如 Redux)中的不可變數據更新、對象合并。
  • 深拷貝:游戲狀態復制、復雜表單數據備份、避免副作用。

四)、總結

  • 淺拷貝:適用于單層對象,使用 Object.assign()、展開語法等。
  • 深拷貝:適用于復雜嵌套對象,推薦使用成熟庫(如 Lodash)或手動遞歸實現。
  • 面試注意點:處理循環引用、特殊對象(如 Date、RegExp)、性能優化(避免過度遞歸)。

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

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

相關文章

”一維前綴和“算法原理及模板

前綴和,就是通過一種方法來求出數組中某個連續區間的元素的和的辦法。我們通常先預處理出來一個前綴和數組,然后把數組中進行元素填充后再進行后續使用。 我們通過一道模板題或許能更加理解其意思。 現在的問題就是:如果我們用暴力枚舉來記錄…

5.13/14 linux安裝centos及一些操作命令隨記

一、環境準備 VMware Workstation版本選擇建議 CentOS 7 ISO鏡像下載指引 虛擬機硬件配置建議(內存/處理器/磁盤空間) 二、系統基礎命令 一、環境準備 1.VMware Workstation版本選擇建議 版本選擇依據 選擇VMware Workstation的版本時&#xff0c…

spring學習->sprintboot

spring IoC(控制翻轉): 控制:資源的控制權(資源的創建,獲取,銷毀等) 反轉:和傳統方式不一樣(用上面new什么),不用new讓ioc來發現你用什么,然后我來給什么 DI:(依賴注入) 依賴:組件的依賴關系。如newsController依賴NewsServi…

iOS 閱后即焚功能的實現

iOS閱后即焚功能實現步驟 一、功能設計要點 消息類型支持:文本、圖片、視頻、音頻等。銷毀觸發條件: 接收方首次打開消息后啟動倒計時。消息存活時間可配置(如5秒、1分鐘)。 安全要求: 端到端加密(E2EE&a…

OpenHarmony 開源鴻蒙南向開發——linux下使用make交叉編譯第三方庫——mqtt庫

準備工作 請依照這篇文章搭建環境 OpenHarmony 開源鴻蒙南向開發——linux下使用make交叉編譯第三方庫——環境配置_openharmony交叉編譯-CSDN博客 下載 wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.5/gnutls-3.5.9.tar.xz 解壓 tar -xf mkdir ./out cd ./out Cmake命…

武漢SMT貼片工藝優化與生產效能提升路徑

內容概要 隨著華中地區電子制造產業集群的快速發展,武漢SMT貼片行業面臨工藝升級與效能提升的雙重挑戰。本文聚焦SMT生產全流程中的關鍵環節,從鋼網印刷精度控制、回流焊溫度曲線優化、AOI檢測系統迭代三大核心工藝出發,結合區域產業鏈特點提…

線程池(ThreadPoolExecutor)實現原理和源碼細節是Java高并發面試和實戰開發的重點

一、線程池核心流程圖 ----------------- | 提交任務 | submit/execute -----------------|v ----------------- | 判斷核心線程數 | < corePoolSize&#xff1f; -----------------|Yes |Nov v [創建新線程] -----------------| 隊列是否滿&a…

學習海康VisionMaster之直方圖工具

一&#xff1a;進一步學習了 今天學習下VisionMaster中的直方圖工具&#xff1a;就是統計在ROI范圍內進行灰度級分布的統計 二&#xff1a;開始學習 1&#xff1a;什么是直方圖工具&#xff1f; 直方圖工具針對輸入灰度圖像的指定ROI區域&#xff0c;輸出該區域的圖像灰度直方…

計算機網絡 : Socket編程

計算機網絡 &#xff1a; Socket編程 目錄 計算機網絡 &#xff1a; Socket編程引言1.UDP網絡編程1.1 網絡地址與端口轉換函數1.2 本地環回1.3 EchoServer1.4 DictServer1.5 DictServer封裝版1.6 簡單聊天室 2.TCP網絡編程2.1 TCP Socket API詳解2.2 Echo Server2.3 Echo Serve…

Elasticsearch/OpenSearch 中doc_values的作用

目錄 1. 核心作用 2. 適用場景 3. 與 index 參數的對比 4. 典型配置示例 場景 1&#xff1a;僅用于聚合&#xff0c;禁止搜索 場景 2&#xff1a;優化大字段存儲 5. 性能調優建議 6. 底層原理 doc_values 是 Elasticsearch/OpenSearch 中用于優化查詢和聚合的列式存儲結…

使用mermaid 語言繪畫時序圖和鏈路圖

給大家展示一下效果&#xff0c; 官方地址&#xff1a;https://mermaid.nodejs.cn/ 官方開發地&#xff1a;https://mermaid.nodejs.cn/intro/#google_vignette graph LR%% 樣式定義&#xff08;完全保留&#xff09; classDef user fill:#E1F5FE,stroke:#0288D1;classDef …

C++ Kafka客戶端(cppkafka)安裝與問題解決指南

一、cppkafka簡介 cppkafka是一個現代C的Apache Kafka客戶端庫&#xff0c;它是對librdkafka的高級封裝&#xff0c;旨在簡化使用librdkafka的過程&#xff0c;同時保持最小的性能開銷。 #mermaid-svg-qDUFSYLBf8cKkvdw {font-family:"trebuchet ms",verdana,arial,…

STM32的ADC模塊中,**采樣時機(Sampling Time)**和**轉換時機(Conversion Time),獲取數據的時機詳解

在STM32的ADC模塊中&#xff0c;**采樣時機&#xff08;Sampling Time&#xff09;和轉換時機&#xff08;Conversion Time&#xff09;**是ADC工作流程中的兩個關鍵階段&#xff0c;直接影響采樣精度和系統實時性。以下是詳細解析&#xff1a; 1. 采樣時機&#xff08;Samplin…

Pageassist安裝(ollama+deepseek-r1)

page-assist網站&#xff1a;https://github.com/n4ze3m/page-assist 首先電腦配置node.js&#xff0c;管理員打開命令窗口輸入下面命令下載bun npm install -g buncd 到你想要安裝page-assist的地方&#xff08;推薦桌面&#xff09; 輸入下列命令 git clone https://gith…

APC 熒光通道專用!Elabscience? CD11b 抗體激發 / 發射光譜精準匹配流式檢測

內容概要 Elabscience APC Anti-Mouse/Human CD11b Antibody [M1/70]&#xff08;貨號&#xff1a;E-AB-F1081E&#xff09;是一款高特異性熒光標記抗體&#xff0c;適用于流式細胞術&#xff08;FCM&#xff09;&#xff0c;可精準檢測小鼠和人類樣本中的 CD11b 髓系細胞&…

entity線段材質設置

在cesium中,我們可以改變其entity線段材質,這里以直線為例. 首先我們先創建一條直線 const redLine viewer.entities.add({polyline: {positions: Cesium.Cartesian3.fromDegreesArray([-75,35,-125,35,]),width: 5,material:material, 保存后可看到在地圖上創建了一條線段…

大模型數據分析破局之路20250512

大模型數據分析破局之路 本文面向 AI 初學者、數據分析從業者與企業技術負責人&#xff0c;圍繞大模型如何為數據分析帶來范式轉變展開&#xff0c;從傳統數據分析困境談起&#xff0c;延伸到 LLM MCP 的協同突破&#xff0c;最終落腳在企業實踐建議。 &#x1f30d; 開篇導語…

【MySQL】索引太多會怎樣?

在 MySQL 中&#xff0c;雖然索引可以顯著提高查詢效率&#xff0c;但過多的索引&#xff08;如超過 5-6 個&#xff09;會帶來以下弊端&#xff1a; 1. 存儲空間占用增加 每個索引都需要額外的磁盤空間存儲索引樹&#xff08;BTree&#xff09;。對于大表來說&#xff0c;多個…

使用PocketFlowSharp創建一個Human_Evaluation示例

效果 實踐 有時候AI生成的結果我們并不滿意在進入下一步之前&#xff0c;我們需要對AI生成的結果進行人工審核&#xff0c;同意了才能進入下一個流程。 Human_Evaluation就是人工判斷的一個簡單示例。 internal class Program{static async Task Main(string[] args){// Load…

【項目】自主實現HTTP服務器:從Socket到CGI全流程解析

00 引言 ? 在構建高效、可擴展的網絡應用時&#xff0c;理解HTTP服務器的底層原理是一項必不可少的技能。現代瀏覽器與移動應用大量依賴HTTP協議完成前后端通信&#xff0c;而這一過程的背后&#xff0c;是由網絡套接字驅動的請求解析、響應構建、數據傳輸等一系列機制所支撐…