前端面試題集錦-2021年前端面試題收集題庫3
阿新 • • 發佈:2021-01-19
常見的javascript 語句基本規範
1.變數和函式的命名規則
- 命名規則-駝峰命名法
- 建構函式首字母大寫
2.空格,縮排,註釋的使用規範
- 一般使用2空格代替tab
- 註釋多行用 /** */
- 單行註釋直接 //
3.其他使用規範
- 判斷變數是否相等時使用
===
強等型別判斷一起 switch
語句必須有default
分支- 使用字面量建立陣列和物件代替
new Array()
- 不要在同一行宣告多個變數
- 不要使用全域性函式
- 函式不應該有時有返回值,有時沒有返回值
eval函式的功能是什麼
定義和用法
用來計算某個字串,並且執行其中的JavaScript程式碼
語法
eval(string)
需要注意的點
- 如果傳入 eval() 的引數不是字串,則會直接返回該引數
- 非嚴格模式下直接呼叫 eval() 時,裡面使用 var 宣告的變數和使用 function 宣告的函式會修改當前詞法作用域,裡面使用 let 和 const 宣告的變數不會修改當前詞法作用域,但是會在當前建立新的詞法作用域。
- 非嚴格模式下間接引用 eval() 時,會直接執行在全域性環境中,裡面使用 var 宣告的變數和使用 function 宣告的函式會修改全域性詞法作用域,裡面使用 let 和 const 宣告的變數不會修改全域性詞法作用域,但是會在全域性環境建立新的詞法作用域
- 使用 window.eval() 等同於間接引用 eval()
- eval() 中執行的程式碼只能呼叫 JS 直譯器(Interpreter)來解釋執行,無法被即時編譯器(JIT Compiler)優化, eval() 中的執行的程式碼可能會導致 JS 引擎在已經生成的機器程式碼中進行變數查詢和賦值,帶來效能問題。
- eval() 使用不當可能會導致裡面執行的字串容易遭受惡意修改,帶來安全問題(比如 XSS 攻擊)。
- 使用 eval() 會干擾程式碼壓縮工具的行為。程式碼壓縮工具一般會將區域性變數名重新命名為更短的變數名(如 a 和 b 等),以便減小程式碼體積。當使用了 eval() 時,由於外部的區域性變數可能會被 eval() 訪問到,程式碼壓縮工具便不會對可能會被 eval() 訪問到的區域性變數名進行壓縮,會降低程式碼壓縮率。
執行一下程式碼結果是什麼["1","2","3"].map(parseInt)
- 上面程式碼主要考察高階函式
map
和parseInt
函式
['1','2','3'].map(parseInt(item,index))
=> parseInt('1',0)
=> parseInt('2',1)
=> parseInt('3',2)
// parseInt 第一個引數為 需要被轉換的字串
// parseInt 第二個引數為 被轉換字串的進位制
// parseInt('2',1) 表示將 1進位制的 字串‘2’轉換為10進位制,不存在1進位制的字串'2',所以返回值為NaN
- 所以最後的返回值為
[1,NaN,NaN]
說說對this物件的理解
this
是 執行上下文- 表示函式執行時的上下文
- 預設指向函式執行的上下文 全域性執行則是window,引用物件呼叫則是引用物件
var name = 'jeskson';
function person() {
return this.name;
}
console.log(this.name); // jeskson
console.log(window.name); // jeskson
console.log(person()); // jeskson
- 使用call和apply可以指定上下文
function person() {
return this.name;
}
var obj = {
name: 'jeskson'
}
console.log(person.call(obj)); // jeskson
console.log(person.apply(obj)); // jeskson
- 建構函式中this指向構造出來的新物件
function Person(name) {
this.name = name;
return name;
}
console.log(new Person('jeskson').name); // jeskson
- 複雜的this指向問題,需要考慮函式執行上下文的出棧和壓棧問題判斷
JavaScript中存在哪些偽陣列,如何將偽陣列轉化為陣列
- 常見的偽陣列:
arguments
document
.getElementsByTagName
獲取的元素標籤集合 - 區別和相似:
- 相似: 都具有
length
屬性,都是有序的引用組合,可以下標獲取元素,偽陣列也是可迭代物件,可以呼叫 for of 區別:Array
.isArray
,偽陣列為false,並且陣列的類方法不能使用,例如遍歷的forEach等
- 相似: 都具有
- 如何轉換:
Array
.from
(偽陣列) 可以將偽陣列轉化為正常的標準陣列Array
.prototype
.slice
.call
(偽陣列) 實際上是呼叫陣列的slice
方法利用偽陣列的可迭代特性,for
of 手動push
到空的標準陣列
JavaScript中的callee和caller的作用是什麼
caller
是JavaScript中函式型別的自由屬性,用來標識函式的呼叫的函式,如果是父函式中引用呼叫子函式,則子函式的caller是父函式,如果函式直接在頂層JavaScript環境中呼叫,那麼caller則是null
- callee 則是函式呼叫時 偽陣列 arguments 的屬性,此屬性返回的是當前函式執行本體,例如
function test(){
console.log(arguments.callee)
}
test()
// 返回值是test函式本身,返回值可以直接呼叫類似 arguments.callee()
- 作用:
- caller 用來朔源,標識函式的呼叫鏈,用來除錯和觀察
- callee 用來函式本身對自身的回撥,例如 遞迴呼叫,可以脫離函式名,通過這個屬性直接呼叫自身
統計字串中字母的個數或統計最多的字母
function countStr(str) {=
let dic = str.split('').reduce((prev,current)=>{
if(prev[current] && prev[current].value === current) ++prev[current].count
else prev[current] = {
value:current,
count:0
}
return prev
},{})
for(let index = 0;index< Object.keys(dic).length;index++){
let k = Object.keys(dic)[index]
console.log(dic[k].value + ' : '+ dic[k].count)
}
}
寫一個函式清除字串前後的空格
- 考察正則
function trim(str) {
if (str && typeof str === "string") {
return str.replace(/(^\s*)|(\s*)$/g,""); //去除前後空白符
}
}
- 另一種方式
function quickTrim(str) {
let temp = str.split('')
let resultArry = temp.reduce((count,ele)=>{
if(ele !== ' ') count.push(ele)
return count
},[])
return resultArry.join('')
}
寫一個函式實現一個數組合並的方法
- 遍歷
b.forEach(ele=>{
a.push(a)
})
- Array自帶的concat方法
a.concat(b)
- 巧用apply和push
- push可以接受多個引數,全部push到數組裡面
- apply會把陣列當作引數組合傳入
a.push.apply(a,b)
工作中,常用的邏輯運算子有哪些
- 與
&&
- 或
||
- 非
!
什麼是事件代理(事件委託)
- 原理
- 事件冒泡:js在處理事件時,如果當前 dom 沒有對事件進行接收和捕獲,事件會順著 dom樹的結構自下往上傳遞,最終在根節點dom
- 實現
- 在 父dom結構上進行事件捕獲和事件處理,通過
Event
target
物件判斷具體觸發物件 - 子元素例如
li
元素不監聽事件,將事件委託給ul
元素處理和捕獲
- 在 父dom結構上進行事件捕獲和事件處理,通過
- 優點
- 減少dom樹的遍歷和dom事件的繫結,效能優化
- 子元素修改或者新增時不需要重新進行事件繫結
未宣告和未定義的變數有什麼區別
- 未宣告
- 記憶體空間沒有開闢
- 沒有這個東西存在
- 不存在 但是直接呼叫
- 或報錯,提示未宣告
- 未定義
- 已開闢記憶體空間
- 但是記憶體空間並沒有東西
- 用來形容這種狀態的 js 資料型別叫做
undefined
什麼是全域性變數,這些變數如何宣告,使用全域性變數有哪些問題
- 作用域
- js 中只有函式可以包裹作用域
- 全域性作用域
- 沒有包裹在函式內部,最外層的作用域
- 怎麼宣告
- 直接在最外層宣告
- 用window物件 宣告
- 不用var 關鍵字,直接寫變數名也會提升到全域性
- 會有什麼問題
- 容易出現變數名衝突,影響全域性
- 不利於回收,出現記憶體效能問題
- 變數和程式碼混亂
常用的定時器工作說明,使用定時器的缺點
- 常用的定時器
- setTimeOut
- 定時一段時間之後執行
- setTimeInterval
- 間隔一段時間重複執行
- setTimeOut
- 清除定時器
- clearTimeInterval
- 只有知道具體的定時器名稱才可以關閉
- 如果不關閉定時器,會一直執行,直到頁面退出,記憶體釋放
- clearTimeInterval
說說ViewState和SessionState有什麼區別
- ViewState 是.net 提出的一種客戶端資料儲存的方式,通過一個隱藏的dom節點,儲存一些可序列化的資料結構
- SessionState 是儲存於服務端的一種資料結構,同主機域名下的所有tab頁面可以共享
- 這個都沒接觸過了
什麼是 ===
運算子
- 強等運算子
- 比較過程中不進行強制型別轉換
- 並且在比較之前優先進行型別判斷,如果資料型別不一樣,直接返回
false