JavaScript面試題看這一篇就夠了,簡單全面一發入魂(持續更新 step1)

      網友投稿 1130 2025-03-31

      目錄


      1、BOM、DOM有什么區別?

      (1)DOM

      (2)BOM

      2、javaScript中代碼后加不加分號;有什么區別?

      3、var與let、const有什么區別?

      4、原始值和引用值有什么區別?

      5、什么是執行上下文?

      6、解釋一下javaScript垃圾回收?

      7、如何判斷一個對象是不是數組?

      8、Object和Map到底有什么區別?

      (1)內存占用

      (2)插入性能

      (3)查找速度

      (4)刪除性能

      9、簡述一下什么是Set?

      (1)基礎API

      (2)順序與迭代

      10、什么是迭代器?

      11、什么是生成器?

      12、JavaScript的繼承是通過什么方式實現的?(問法2:什么是原型鏈?問法3:構造函數、原型、實例三者的關系?)

      13、以下表達式,對嗎?為什么?

      14、apply()和call()有什么區別?

      15、函數聲明和函數表達式有什么區別?

      1、BOM、DOM有什么區別?

      (1)DOM

      文檔對象模型(DOM,Document Object Model)是一個應用編程接口(API),用于在HTML中使用擴展的HTML。DOM將整個頁面抽象為一組分層節點。

      DOM通過創建表示文檔的樹,讓開發者可以隨心所欲的控制網頁的內容和結構。使用DOM API可以輕松地刪除、添加、替換、修改節點。

      對瀏覽器而言,DOM就是使用ECMAScript實現的,如今已經成為JavaScript語言的一大組成部分。

      言而言之,DOM提供與網頁內容交互的方法和接口。

      (2)BOM

      IE3和Netscape Navigator3提供了瀏覽器對象模型(BOM)API,用于支持訪問和操作瀏覽器的窗口。使用BOM,開發者可以操控瀏覽器顯示頁面之外的部分。

      BOM的能力展示:

      彈出新瀏覽器窗口的能力;

      移動、縮放和關閉瀏覽器窗口的能力;

      navigator對象,提供關于瀏覽器的詳盡信息;

      location對象,提供瀏覽器加載頁面的詳盡信息;

      screen對象,提供關于用戶屏幕分辨率的詳盡信息;

      performance對象,提供瀏覽器內存占用、導航行為和時間統計的詳盡信息;

      對cookie的支持;

      其它自定義對象,如XMLHttpRequest和IE的ActiveXObject。

      簡而言之,BOM提供與瀏覽器交互的方法和接口。

      2、JavaScript中代碼后加不加分號;有什么區別?

      加分號有助于防止省略造成的問題

      避免輸入內容不完整

      便于開發者通過刪除空行來壓縮代碼(如果沒有結尾的分號,只刪除空行,則會導致語法錯誤)

      加分號有助于提升性性能,因為解析器會嘗試在合適的位置補上分號以糾正語法錯誤。

      3、var與let、const有什么區別?

      let不具備聲明提升,var具備聲明提升

      let聲明的范圍是塊作用域,而var聲明的范圍是函數作用域。

      let是ES6才引入的聲明關鍵字

      for循環中的let聲明

      const與let很相似,最大的區別是const必須初始化,且不能再次賦值。

      結語:

      不使用var,有了let和const,大多數開發者會發現自己不再需要var了,限制自己只使用let和const,有助于提升代碼質量,因為變量有了明確的作用域、聲明位置、以及不變的值。

      const優先,let次之。使用const聲明可以讓瀏覽器運行時強制保持變量不變,也可以讓靜態代碼分析工具提前發現不合法的賦值操作。

      4、原始值和引用值有什么區別?

      原始值大小固定,保存在棧內存中

      從一個變量到另一個變量復制原始值,會創建該值得第二個副本

      引用值是對象,存儲在堆內存中

      包含引用值的變量實際上只包含指向相應對象的一個指針,而不是對象本身

      從一個變量到另一個變量復制引用值,只會復制指針,因此結果是兩個變量都指向同一個對象

      typeof操作費可以確定值的原始類型,instanceof操作符用于確保值得引用類型

      5、什么是執行上下文?

      任何變量都存在于某個執行上下文中(也稱為作用域)。這個上下文(作用域)決定了變量的生命周期,以及它們可以訪問代碼的哪些部分。

      執行上下文可以總結如下:

      執行上下文分為 ① 全局上下文、② 函數上下文、③ 塊級上下文

      代碼執行流每進入一個新上下文,都會創建一個作用域鏈,用于搜索變量和函數

      函數或塊的局部上下文不僅可以訪問自己作用域內的變量,也可以訪問任何包含上下文乃至全局上下文的變量

      全局上下文只能訪問全局上下文中的變量和函數,不能直接訪問局部上下文中的任何數據

      變量的執行上下文用于確定什么時候釋放內存

      6、解釋一下JavaScript垃圾回收?

      JavaScript是使用垃圾回收的編程語言,開發者不需要操心內存分配和回收。

      離開作用域的值會被自動標記為可回收,然后在垃圾回收期間被刪除

      主流的垃圾回收算法是標記算法,即先給當前不使用的值加上標記,再回來回收它們的內存

      引用計數是另一種垃圾回收策略,需要記錄值被引用了多少次。JavaScript引擎不再使用這種算法,但某些舊版本的IE仍然會受這種算法的影響,原因是JavaScript會訪問非原生JavaScript對象(如DOM對象)。

      引用計數在代碼中循環引用時會出現問題

      解除變量的引用不僅可以消除循環引用,而且對垃圾回收也有幫助。為促進內存回收,全局對象、全局對象的屬性和循環引用都應該在不需要時解除引用。

      7、如何判斷一個對象是不是數組?

      在只有一個全局作用域的時候,使用instanceof操作符就足矣:

      if(value instanceof Array){ //操作數組 }

      1

      2

      3

      使用instanceof的前提是只有一個全局執行上下文,如果網頁里有多個框架,則可能涉及兩個不同的全局上下文,因此就會有兩個不同版本的Array構造函數。如果要把數組從一個框架傳到另一個框架,則這個數組的構造函數將有別于第二個框架內本地創建的數組。

      為了解決這個問題,ECMAScript提供了 Array.isArray()方法。這個方法的目的就是確定一個值是否為數組,而不用管它是在哪個全局執行上下文中創建的。

      if(Array.isArray(value)){ //操作數組 }

      1

      2

      3

      8、Object和Map到底有什么區別?

      (1)內存占用

      給定固定大小內存的情況下,Map一般會比Object多存儲50%的鍵值對。

      (2)插入性能

      插入Map一般會稍微快一點。

      (3)查找速度

      相差無幾。

      (4)刪除性能

      Map的刪除性能完勝Object。

      綜上四點,選擇Map顯然是更好地選擇。

      9、簡述一下什么是Set?

      (1)基礎API

      添加add()

      查詢has()

      獲取數量size

      刪除delete()

      清空clear()

      (2)順序與迭代

      Set會維護值插入時的順序,因此支持按順序迭代。

      集合實例可以提供一個迭代器Iterator,能以插入順序生成集合內容??梢酝ㄟ^values()方法及其別名方法keys(),或者Symbol.iterator屬性,他引用values(),取得這個迭代器。

      const s = new Set("哪吒","云韻","比比東"); alert(s.keys === s[Symbol.iterator]);//true alert(s.values === s[Symbol.iterator]);//true for(let value of s.values()){ } for(let value of s[Symbol.iterator]){ }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      因為values()是默認迭代器,所以可以直接對集合實例使用擴展操作,把集合轉為數組:

      const s = new Set("哪吒","云韻","比比東"); console.log([...s]);//["哪吒","云韻","比比東"]

      JavaScript面試題看這一篇就夠了,簡單全面一發入魂(持續更新 step1)

      1

      2

      10、什么是迭代器?

      迭代器是一個可以由任意對象實現的接口,支持連續獲取對象產出的每一個值。任何實現Iterable接口的對象都有一個Symbol.iterator屬性,這個屬性引用默認迭代器。默認迭代器就像一個迭代器工廠,也就是一個函數,調用之后會產生一個實現Iterator接口的對象。

      迭代器必須通過連續調用next()方法才能連續獲取值,這個方法返回一個IteratorObject。這個對象包含一個done屬性和一個value屬性。前者時刻一個布爾值,表示十分還有更多值可以訪問;后者包含迭代器返回的當前值。這個接口可以通過手動反復調用next()方法來消費,也可以通過原生消費者,比如for循環來自動消費。

      11、什么是生成器?

      生成器是ECMAScript6新增的一個極為靈活的結構,擁有在一個函數塊內暫停和恢復代碼執行的能力。這種新能力具有較深遠的影響,比如,使用生成器可以自定義迭代器和實現協程。

      生成器的形式是一個函數,函數名稱前面加一個星號*,表示它是一個生成器。只要是可以定義函數的地方,就可以定義生成器。

      調用生成器函數會產生一個生成器對象,生成器對象一開始處于暫停執行(suspended)狀態。與迭代器相似,生成器對象也實現了Iterator接口,因此具有next()方法。調用這個方法會讓生成器開始或恢復執行。

      next()方法的返回值類似于迭代器,有一個done屬性和一個value屬性。函數體為空的生成器函數中間不會停留,調用一次next()就會讓生成器到達done:true狀態。

      12、JavaScript的繼承是通過什么方式實現的?(問法2:什么是原型鏈?問法3:構造函數、原型、實例三者的關系?)

      ECMA-262把原型鏈定義為ECMAScript的主要繼承方式。其基本思想就是通過原型繼承多個引用類型的屬性和方法。

      每個構造函數都有一個原型對象,原型有一個屬性指回構造函數,而實例有一個內部指針指向原型。如果原型是另一個類型的實例呢?那就意味著這個原型本身有一個內部指針指向另一個原型,相應地另一個原型也有一個指針指向另一個構造函數,這樣就在實例和原型之間構造了一條原型鏈。

      13、以下表達式,對嗎?為什么?

      console.log(sum(1,2)); function sum(num1,num2){ return num1+num2; }

      1

      2

      3

      4

      JavaScript引擎在任何代碼執行之前,會先讀取函數聲明,并在執行上下文中生成函數定義。而函數表達式必須等到代碼執行到它那一行,才會在執行上下文中生成函數定義。

      所以,以上代碼是可以正常運行的,因為函數聲明會在任何代碼執行之前先被讀取并添加到執行上下文,這個過程叫做函數聲明提升。

      在執行代碼時,JavaScript引擎會先執行一遍掃描,把發現的函數聲明提升到源代碼樹的頂部。因此即使函數定義出現在它們的代碼之后,引擎也會把函數聲明提升到頂部。

      如果把前面代碼中的函數聲明改為等價的函數表達式,那么執行的時候就會出錯。

      console.log(sum(1,2)); let sum = function sum(num1,num2){ return num1+num2; }

      1

      2

      3

      4

      14、apply()和call()有什么區別?

      這兩個方法都會以制定的this值來調用函數,即會設置調用函數時函數體內的this對象的值。

      apply()接收兩個參數,函數體this的值和一個參數數組。第二個對象是Array的實例,也可以是arguments對象。

      call()和apply()的作用是一樣的,只是傳入參數的形式不一樣。call()傳入的不是數組或arguments對象,而是將參數一個一個的傳入。

      apply()和call()真正的用處不在于傳遞參數,而在于控制this。

      window.color = 'red'; let o = { color:'blue'; } function getColor(){ console.log(this.color); } getColor(); //red getColor().call(this);//red getColor().call(window);//red getColor().call(o);//blue

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      15、函數聲明和函數表達式有什么區別?

      函數聲明是這樣的:

      function functionNam(arg0,arg1,arg2){ //函數體 }

      1

      2

      3

      函數式聲明的關鍵特點是函數聲明提升,即函數聲明會在代碼執行前獲得定義。

      函數表達式是什么?

      let functionName = function(arg0.arg1,arg2){ //函數體 }

      1

      2

      3

      函數表達式看起來就像一個普通的變量定義和賦值,即創建一個函數再把它賦值給一個變量functionName。這樣創建的函數叫做匿名函數,因為function關鍵字后面沒有標識符。匿名函數有時也被成為蘭姆達函數。

      函數表達式和其他表達式一樣,需要先賦值再使用,所以如下代碼就是錯誤的。

      sayHello(); let sayHello = function(){ console.log("hello world"); }

      1

      2

      3

      4

      函數聲明和函數表達式的根本區別在于理解提升。

      JavaScript 數據結構

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:制造業生產管理跳槽(生產計劃跳槽方向)
      下一篇:Excel多維引用示例的數據來源
      相關文章
      亚洲中文字幕无码久久精品1 | 亚洲精品一级无码中文字幕 | 最新精品亚洲成a人在线观看| 亚洲精华国产精华精华液好用 | 亚洲五月午夜免费在线视频| 亚洲AV无码资源在线观看| 亚洲精品二三区伊人久久| 亚洲午夜精品在线| 亚洲国产精品白丝在线观看| 亚洲精品视频专区| 亚洲天堂中文字幕| 78成人精品电影在线播放日韩精品电影一区亚洲 | 在线亚洲v日韩v| 亚洲成AV人片在WWW| 亚洲欧美不卡高清在线| 亚洲熟妇久久精品| 亚洲乱妇熟女爽到高潮的片| 亚洲日韩av无码| 午夜亚洲福利在线老司机| 亚洲av午夜国产精品无码中文字| 亚洲乱色伦图片区小说| 亚洲精品无码mⅴ在线观看| 亚洲欧美日韩中文高清www777| 亚洲偷自拍另类图片二区| 亚洲熟妇AV日韩熟妇在线| 亚洲精品中文字幕| 偷自拍亚洲视频在线观看| 日韩精品电影一区亚洲| 亚洲一级黄色视频| 夜夜春亚洲嫩草影院| 亚洲国产精品无码久久久蜜芽 | 亚洲av无码日韩av无码网站冲| 亚洲AV无码之国产精品| 国产亚洲精品第一综合| 亚洲午夜精品第一区二区8050| 亚洲无线观看国产精品| 亚洲国产成人久久精品动漫| 自怕偷自怕亚洲精品| 亚洲精品福利你懂| 婷婷国产偷v国产偷v亚洲| 亚洲国产精品一区二区九九|