36 個JS 面試題為你助力金九銀十(面試必讀)
- 2019 年 10 月 11 日
- 筆記
1.JS中let
和const
有什麼用?
在現代js中,let
&const
是創建變數的不同方式。 在早期的js中,咱們使用var
關鍵字來創建變數。 let
&const
關鍵字是在ES6版本中引入的,其目的是在js中創建兩種不同類型的變數,一種是不可變的,另一種是可變的。
const:它用於創建一個不可變變數。不可變變數是指其值在程式的整個生命周期中永不改變的變數。
let: let
用於創建一個可變變數,可變變數是像var
這樣的普通變數,可以任意次數地更改。
2. JS 中的主要有哪幾類錯誤
JS有三類的錯誤:
載入時錯誤:載入web頁面時出現的錯誤(如語法錯誤)稱為載入時錯誤,它會動態生成錯誤。
運行時錯誤:由於濫用HTML語言中的命令而導致的錯誤。
邏輯錯誤:這些錯誤是由於對具有不同操作的函數執行了錯誤的邏輯而導致的
3. 如何通過類別名獲取 dom 元素
在 JS 中使用document.
get
El
em
entsByClassName()
方法來獲取具有類名的元素。
4.JS的作用域鏈是什麼及其作用
一般情況下,變數取值到創建這個變數的函數的作用域中取值。但是如果在當前作用域中沒有查到值,就會向上級作用域去查,直到查到全局作用域,這麼一個查找過程形成的鏈條就叫做作用域鏈。
JS中的作用域鏈主要用於解析變數的值。 如果沒有這個,在不同的作用域內定義了許多變數,JS很難為變數選擇某個值。
5.解釋JS中的MUL
函數
MUL
表示數的簡單乘法。在這種技術中,將一個值作為參數傳遞給一個函數,而該函數將返回另一個函數,將第二個值傳遞給該函數,然後重複繼續。例如:x*y*z
可以表示為
function mul (x) { return function (y) { return function (z) { return x * y * z; } } }
6.用純JS編寫一個程式來反轉字元串
使用內置函數:內置函數reverse()
直接反轉字元串。
str="jQuery"; str = str.split("") str = str.reverse() str = str.join("") alert(str);
首先將字元串拆分為數組,然後反轉數組,最近將字元連接起來形成字元串。
使用循環:首先,計算字元串中的字元數,然後對原始字元串應用遞減循環,該循環從最後一個字元開始,列印每個字元,直到count變為零。
7.JS中如何將頁面重定向到另一個頁面?
- 使用 location.href:
window.location.href =「
https
://www.onlineinterviewquestions.com/」
- 使用 location.replace:
window.location.replace("
http
s://www.onlineinterviewquestions.com/;");
8. 列出JS中的一些設計模式:
設計模式是軟體設計中常見問題的通用可重用解決方案,以下是一些設計模式是:
創建模式:該模式抽象了對象實例化過程。
結構型模式:這些模式處理不同的類和對象以提供新功能。
行為模式:也稱發布-訂閱模式,定義了一個被觀察者和多個觀察者的、一對多的對象關係。
並行設計模式:這些模式處理多執行緒編程範例。
架構設計模式:這些模式用於處理架構設計。
9. JS中的Array.
splice
()
和Array.
slice
()
方法有什麼區別
話不多說,來看第一個例子:
var arr=[0,1,2,3,4,5,6,7,8,9];//設置一個數組 console.log(arr.slice(2,7));//2,3,4,5,6 console.log(arr.splice(2,7));//2,3,4,5,6,7,8 //由此我們簡單推測數量兩個函數參數的意義, slice(start,end)第一個參數表示開始位置,第二個表示截取到的位置(不包含該位置) splice(start,length)第一個參數開始位置,第二個參數截取長度
接著看第二個:
var x=y=[0,1,2,3,4,5,6,7,8,9] console.log(x.slice(2,5));//2,3,4 console.log(x);[0,1,2,3,4,5,6,7,8,9]原數組並未改變 //接下來用同樣方式測試splice console.log(y.splice(2,5));//2,3,4,5,6 console.log(y);//[0,1,7,8,9]顯示原數組中的數值被剔除掉了
slice
和splice
雖然都是對於數組對象進行截取,但是二者還是存在明顯區別,函數參數上slice
和splice
第一個參數都是截取開始位置,slice
第二個參數是截取的結束位置(不包含),而splice
第二個參數(表示這個從開始位置截取的長度),slice
不會對原數組產生變化,而splice
會直接剔除原數組中的截取數據!
10.如何在JS中動態添加/刪除對象的屬性?
咱們可以使用object.property_name = value
向對象添加屬性,delete object.property_name
用於刪除屬性。
例如:
let user = new Object(); // adding a property user.name='Anil'; user.age =25; console.log(user); delete user.age; console.log(user);
11.解釋一下什麼是 promise ?
promise
是js中的一個對象,用於生成可能在將來產生結果的值。 值可以是已解析的值,也可以是說明為什麼未解析該值的原因。
promise 可以有三種狀態:
- pending:初始狀態,既不是成功也不是失敗
- fulfilled:意味著操作完全成功
- rejected:意味著操作失敗
一個等待狀態的promise對象能夠成功後返回一個值,也能失敗後帶回一個錯誤 當這兩種情況發生的時候,處理函數會排隊執行通過then方法會被調用
12. 數組去重復的方法有哪些
1.使用 set
function uniquearray(array) { let unique_array= Array.from(set(array)) return unique_array; }
2.使用 filter
function unque_array (arr) { let unique_array = arr.filter(function(elem, index, self) { return index == self.indexOf(elem); }) return unique_array; } console.log(unique_array(array_with_duplicates));
3.使用 for
循環
Array dups_names = ['Ron', 'Pal', 'Fred', 'Rongo', 'Ron']; function dups_array(dups_names) { let unique = {}; names.forEach(function(i) { If (!unique[i]) { unique[i] = true; } }); return Object.keys(unique);} // Ron, Pal, Fred, Rongo Dups_array(names);
13. undefined,null 和 undeclared 有什麼區別?
1.null表示"沒有對象",即該處不應該有值,轉為數值時為0。典型用法是:
(1) 作為函數的參數,表示該函數的參數不是對象。
(2) 作為對象原型鏈的終點。
2.undefined表示"缺少值",就是此處應該有一個值,但是還沒有定義,轉為數值時為NaN。典型用法是:
(1)變數被聲明了,但沒有賦值時,就等於undefined。
(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
(3)對象沒有賦值的屬性,該屬性的值為undefined。
(4)函數沒有返回值時,默認返回undefined。
3.undeclared:js語法錯誤,沒有申明直接使用,js無法找到對應的上下文。
14.列出JS基本和非基本數據類型之間的一些區別?
1.目前JS中有6
種基本數據類型: Undefined
、Null
、Boolean
、Number
、Symbol
和 String
。還有1種複雜的數據類型————Object
,Object
本質上是由一組無序的名值對組成的。Object
、Array
和Function
則屬於引用類型。
2.基本數據類型是不可變的,而非基本數據類型是可變的。
3.基本數據類型是不可變的,因為它們一旦創建就無法更改,但非基本數據類型剛可更改,意味著一旦創建了對象,就可以更改它。
4.將基本數據類型與其值進行比較,這意味著如果兩個值具有相同的數據類型並具有相同的值,那麼它們是嚴格相等的。
5.非基本數據類型不與值進行比較。例如,如果兩個對象具有相同的屬性和值,則它們嚴格不相等。
15. 如何在現有函數中添加新屬性
只需給現有函數賦值,就可以很容易地在現有函數中添加新屬性。例如,現有一個對象person
,通過下面的程式碼來為 person
添加新的屬性:
person.country= 「India」;
16. JS中的深拷貝與淺拷貝的區別?
- 深拷貝遞歸地複製新對象中的所有值或屬性,而拷貝只複製引用。
- 在深拷貝中,新對象中的更改不會影響原始對象,而在淺拷貝中,新對象中的更改,原始對象中也會跟著改。
- 在深拷貝中,原始對象不與新對象共享相同的屬性,而在淺拷貝中,它們具有相同的屬性。
17. 如何在JavaScript中每x秒調用一個函數
在JS中,咱們使用函數 setInterval
()
在每x
秒內調用函數。如:
setInterval(function (){ alert("Hello"); }, 3000);
18. 解釋一下JS的展開操作符?
展開運算符在需要多個參數/變數/元素的位置展開表達式,它用三個點(...
)。如:
var mid = [3, 4]; var newarray = [1, 2, ...mid, 5, 6]; console.log(newarray); // [1, 2, 3, 4, 5, 6]
19. JS中的宿主對象與原生對象有何不同?
宿主對象:這些是運行環境提供的對象。這意味著它們在不同的環境下是不同的。例如,瀏覽器包含像windows
這樣的對象,但是Node.js環境提供像Node List
這樣的對象。
原生對象:這些是JS中的內置對象。它們也被稱為全局對象,因為如果使用JS,內置對象不受是運行環境影響。
20. 解釋JS中的高階函數?
高階函數是JS函數式編程的最佳特性。它是以函數為參數並返回函數作為結果的函數。一些內置的高階函數是map
、filter
、reduce
等等。
21. JS 中 == 和 === 區別是什麼?
1、對於string
,number
等基礎類型,==
和===
有區別
1)不同類型間比較,==
之比較「轉化成同一類型後的值」看「值」是否相等,===
如果類型不同,其結果就是不等。 2)同類型比較,直接進行「值」比較,兩者結果一樣。
2、對於Array
,Object
等高級類型,==
和===
沒有區別
進行「指針地址」比較。
3、基礎類型與高級類型,==
和===
有區別
1)對於==
,將高級轉化為基礎類型,進行「值」比較。 2)因為類型不同,===
結果為false
。
22. JS中的匿名函數是什麼?
匿名函數:就是沒有函數名的函數,如:
(function(x, y){ alert(x + y); })(2, 3);
這裡創建了一個匿名函數(在第一個括弧內),第二個括弧用於調用該匿名函數,並傳入參數。
23. 是否可以在JS中執行301重定向?
JS完全運行在客戶端上。301
是伺服器作為響應發送的響應程式碼。因此,在JS中不可能執行301
重定向。
24. 解釋JS中的事件冒泡和事件捕獲
事件捕獲和冒泡: 在HTML DOM API中,有兩種事件傳播方法,它們決定了接收事件的順序。兩種方法是事件冒泡和事件捕獲。第一個方法事件冒泡將事件指向其預期的目標,第二個方法稱為事件捕獲,其中事件向下到達元素。
事件捕獲
捕獲過程很少被使用,但是當它被使用時,它被證明是非常有用的。這個過程也稱為滴流模式
。在這個過程中,事件首先由最外層的元素捕獲,然後傳播到最內部的元素。例如:
<div> <ul> <li></li> </ul> </div>
從上面的示例中,假設單擊事件發生在li
元素中,在這種情況下,捕獲事件將首先處理div
,然後處理ul
,最後命中目標元素li
。
事件冒泡
冒泡的工作原理與冒泡類似,事件由最內部的元素處理,然後傳播到外部元素。
<div> <ul> <li></li> </ul> </div>
從上面的例子中,假設cli
ck
事件確實發生在冒泡模型中的li
元素中,該事件將首先由li
處理,然後由ul
處理,最後由div
元素處理。
24. 如何將文件的所有導出作為一個對象?
import * as objectname from 『./file.js』
用於將所有導出的成員導入為對象。 可以使用對象的點(.
)運算符來訪問導出的變數或方法,如:
objectname.member1; objectname.member2; objectname.memberfunc();
25. 解釋一下什麼是箭頭函數?
箭頭函數是在es6
或更高版本中編寫函數表達式的簡明方法。箭頭函數不能用作構造函數,也不支援this
,arguments
,super
或new.target
關鍵字,它最適合非方法函數。 通常,箭頭函數看起來像 const function_name =()={}
。
const greet=()=>{console.log('hello');} greet();
25 解釋 JS 中的函數提升
JS允許將聲明移動到頂部的默認行為稱為提升。JS中創建函數的兩種方法是函數聲明和函數表達式。
函數聲明
具有特定參數的函數稱為函數聲明,在JS中創建變數稱為聲明。如:
hoisted(); // logs "foo" function hoisted() { console.log('foo'); }
函數表達式
當使用表達式創建函數時,稱為函數表達式。如:
notHoisted(); // TypeError: notHoisted is not a function var notHoisted = function() { console.log('bar'); };
26. module.exports 和 exports 之間有什麼區別?
module
和exports
是Node.js
給每個js
文件內置的兩個對象。可以通過console.log(module)
和console.log(exports)
列印出來。如果你在m
ai
n.js
中寫入下面兩行,然後運行$
node
main.js
:
console.log(exports);//輸出:{} console.log(module);//輸出:Module {..., exports: {}, ...} (註:...代表省略了其他一些屬性)
從列印咱們可以看出,module.exports
和exports
一開始都是一個空對象{}
,實際上,這兩個對象指向同一塊記憶體。這也就是說module.exports
和exports
是等價的(有個前提:不去改變它們指向的記憶體地址)。
例如:exports.age = 18
和module.export.age = 18
,這兩種寫法是一致的(都相當於給最初的空對象{}
添加了一個屬性,通過require
得到的就是{age: 18}
)。
27. import 和 exports 是什麼?
import
和exports
幫助咱們編寫模組化的JS程式碼。使用import
和exports
,咱們可以將程式碼分割成多個文件。import
只允許獲取文件的某些特定變數或方法。可以導入模組導出的方法或變數。
//index.js import name,age from './person'; console.log(name); console.log(age); //person.js let name ='Sharad', occupation='developer', age =26; export { name, age};
28. 列出一些單元測試框架
下面是一些最流行的JS單元測試框架:
- Unit.js
- Jasmine
- Karma
- Chai
- AVA
- Mocha
- JSUnit
- QUnit
- Jest
29. JS中有哪些不同類型的彈出框可用
在JS中有三種類型的彈出框可用,分別是:
- Alert
- Confirm
- Prompt
30. 如何將 JS 日期轉換為ISO標準
toISOString() 方法用於將js日期轉換為ISO標準。 它使用ISO標準將js Date對象轉換為字元串。如:
var date = new Date(); var n = date.toISOString(); console.log(n); // YYYY-MM-DDTHH:mm:ss.sssZ
31. 如何在JS中克隆對象
Object.assign()
方法用於在JS中克隆對象。如:
var x = {myProp: "value"}; var y = Object.assign({}, x);
32. 如何在JS中編碼和解碼 URL
encodeURI() 函數用於在JS中對URL進行編碼。它將url
字元串作為參數並返回編碼的字元串。
注意: encodeURI()
不會編碼類似這樣字元: / ? : @ & = + $ #
,如果需要編碼這些字元,請使用encodeURIComponent()
。 用法:
var uri = "my profile.php?name=sammer&occupation=pāntiNG"; var encoded_uri = encodeURI(uri);
decodeURI() 函數用於解碼js中的URL。它將編碼的url
字元串作為參數並返回已解碼的字元串,用法:
var uri = "my profile.php?name=sammer&occupation=pāntiNG"; var encoded_uri = encodeURI(uri); decodeURI(encoded_uri);
33. BOM 和 DOM 的關係
BOM全稱Browser Object Model
,即瀏覽器對象模型,主要處理瀏覽器窗口和框架。
DOM
全稱Document Object Model
,即文檔對象模型,是 HTML 和XML 的應用程式介面(API),遵循W3C 的標準,所有瀏覽器公共遵守的標準。
JS是通過訪問BOM(Browser Object Model)對象來訪問、控制、修改客戶端(瀏覽器),由於BOM的window
包含了document
,window
對象的屬性和方法是直接可以使用而且被感知的,因此可以直接使用window
對象的document
屬性,通過document屬性就可以訪問、檢索、修改XHTML文檔內容與結構。因為document
對象又是DOM
的根節點。
可以說,BOM
包含了DOM
(對象),瀏覽器提供出來給予訪問的是BOM
對象,從BOM
對象再訪問到DOM
對象,從而js可以操作瀏覽器以及瀏覽器讀取到的文檔。
34. JS中的substr
()
和substring
()
函數有什麼區別
substr()
函數的形式為substr(startIndex,length)
。 它從startIndex
返回子字元串並返回'length
'個字元數。
var s = "hello"; ( s.substr(1,4) == "ello" ) // true
substring()
函數的形式為substring(startIndex,endIndex)
。 它返回從startIndex
到endIndex - 1
的子字元串。
var s = "hello"; ( s.substring(1,4) == "ell" ) // true
35. 解釋一下 "use strict" ?
「use strict」
是Es5中引入的js指令。 使用「use strict」
指令的目的是強制執行嚴格模式下的程式碼。 在嚴格模式下,咱們不能在不聲明變數的情況下使用變數。 早期版本的js忽略了「use strict」
。
36.解釋 JS 事件委託模型?
在JS中,有一些很酷的東西。其中之一是委託模型。當捕獲和冒泡時,允許函數在一個特定的時間實現一個處理程式到多個元素,這稱為事件委託。事件委託允許將事件偵聽器添加到父節點而不是指定的節點。這個特定的偵聽器分析冒泡事件,以找到子元素上的匹配項。