千鋒教育web前端高頻面試題視頻教程,kerwin大話前端面試秘籍(附答案)

Js常見的面試題
一,js中有哪些內置對象?
答:
① 數(shù)據(jù)封裝類對象:Object,Array,Boolean,Number,String
② 其他對象:Function ,Arguments,Math,Date,RegExp,Error
③ ES6新增對象:Symbol(標識唯一的ID),Map,Set,Promise,Reflect
?
補充:
(一)什么是數(shù)據(jù)封裝類對象?===>一般稱為包裝類/包裝對象
答:在JavaScript中,數(shù)據(jù)封裝類對象是指通過構造函數(shù)創(chuàng)建的對象,用于封裝數(shù)據(jù)和相關的方法。這些對象通常包含私有屬性和公共方法,可以通過實例化對象來訪問和操作這些屬性和方法。
數(shù)據(jù)封裝類對象的目的是將數(shù)據(jù)和操作數(shù)據(jù)的方法封裝在一起,以提高代碼的可維護性和重用性。通過封裝,可以隱藏對象的內部實現(xiàn)細節(jié),只暴露必要的接口給外部使用。我們都知道js分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型。
基本數(shù)據(jù)類型數(shù)據(jù)可以有屬性嗎?答案是沒有,但是為什么基本數(shù)據(jù)類型卻可以調用一些方法呢?
?
var str="hello world";
??var long=str.length;
??console.log(long);??//得出結果為11
?
明明沒有屬性卻可以調用length的屬性,就是因為包裝類的原因,函數(shù)在執(zhí)行的前一刻發(fā)現(xiàn)你寫的代碼其實是存在問題的,但是因為js是解釋型語言,系統(tǒng)會為你進行包裝類的操作。js中提供了三種特殊的引用類型(String Number Boolean)每當我們給基本數(shù)據(jù)類型賦屬性值時 后臺都會給我們偷偷轉換 調用包裝類。為了更好的理解,請看例子:
?
例子1:
var str="hello word";
?//var str = new String("hello world"); // 1.創(chuàng)建出一個和基本類型值相同的對象
?//var long = str.length; // 2.這個對象就可以調用包裝對象下的方法,并且返回結果給long變量
?//str = null;?//?3.之后這個臨時創(chuàng)建的對象就被銷毀了
?var long=str.length; //因為str沒有l(wèi)ength屬性 所以執(zhí)行這步之前后臺會自動執(zhí)行以上三步操作
?console.log(long);??// (結果為:10)
?
?
例子2:
var a = 100;
console.log(a);
console.log(a instanceof Object);
console.log(a.toString());
console.log(a instanceof Object);
//a.toString執(zhí)行到這一行的時候的步驟
1、a = new Number(a); 先把數(shù)字基本值轉化為包裝對象
2、a.toString; 調用的其實是包裝對象的原型當中的toString方法
3、調用結束后自動再讓a變回基本值 a = 100;
?
?
二,如何最小化重繪(repaint)和回流/重排(reflow)?
答:
① 需要對元素進行復雜的操作時,可以先隱藏(display:“none”),操作完成后再顯示
② 需要創(chuàng)建多個DOM節(jié)點時,使用DocumentFragment創(chuàng)建完成后一次性的加入document
③ 緩存Layout屬性值,如:var left=element.offsetLeft?這樣,多次使用left 只會產生一次回流
④ 盡量避免用table布局(table元素一旦觸發(fā)回流就會導致table里面所有的其他元素回流)
⑤ 如果需要修改多個元素的樣式,可以將它們的樣式修改放在一個批處理中,這樣可以減少重繪和回流的次數(shù)。
?
?
補充:
(一)什么是重繪和回流?
答:
① 重繪:指的是當前元素的樣式(背景顏色、字體顏色等)發(fā)生改變的時候(不改變布局,不影響其他的dom),瀏覽器只需要把改變的元素重新的渲染一下即可,重繪對瀏覽器的性能影響較小,所以 一般不考慮。
② 回流/重排;指的是瀏覽器為了重新渲染部分或者全部的DOM而重新計算DOM中元素的位置和幾何構造的過程。(重繪不一定需要重排(比如顏色的改變),重排必然導致重繪(比如改變網頁位置)
?
(二)瀏覽器解析HTML的基本過程?
答:
① 用戶輸入網址,瀏覽器向服務器發(fā)出請求,服務器返回html文件
② 瀏覽器載入html代碼,發(fā)現(xiàn)標簽內有一個標簽引用外部css文件
③ 瀏覽器又發(fā)出css文件的請求,服務器返回這個css文件
④ 瀏覽器繼續(xù)載入html中的部分的代碼,并且css文件已經拿到手了,可以渲染頁面
⑤ 瀏覽器在代碼中發(fā)現(xiàn)一個標簽引用關了一張圖片,向服務器發(fā)出請求。此時瀏覽器不會等到圖片下載完,而是繼續(xù)渲染后面的代碼
⑥ 服務器返回圖片文件,由于圖片占用了一定面積,影響了后面段落的排布,因此瀏覽器需要回過頭來渲染這部分代碼
⑦ 瀏覽器發(fā)現(xiàn)了一個包含一行javascript代碼的script標簽,趕快運行它
⑧ javascript腳本執(zhí)行了這條語句,命令瀏覽器隱藏代碼中某個,杯具了,突然就少了一個元素,瀏覽器不得不重新渲染這部分代碼
⑨ 終于等到的到來,瀏覽器淚流滿面
⑩ 等等,還沒完,用戶點了一個界面中的“換膚”按鈕,javascript讓瀏覽器換了一個標簽中的css的路徑
? 瀏覽器召集了在座的各位:”大伙需要收拾下行李,咱得重新來過”,瀏覽器向服務器請求了新的css文件,重新渲染頁面當頁面的布局發(fā)生變化時,瀏覽器會回過頭來重新渲染,這就是頁面變慢的原因。
(三)緩存Layout屬性值,如:var left=element.offsetLeft?這樣,多次使用left 只會產生一次回流?什么意思呢?
答:這句話的意思是,當我們需要多次使用一個元素的偏移左邊距(left)屬性值時,可以將這個屬性值緩存在一個變量中,這樣就只會觸發(fā)一次回流操作。
?
?
?
三,?說說你對javaScript中的作用域鏈的理解?
答:
JavaScript中的作用域鏈是指變量和函數(shù)的訪問規(guī)則。當在一個函數(shù)內部訪問一個變量時,JavaScript引擎會首先在當前函數(shù)的作用域中查找該變量,如果找不到,就會繼續(xù)在外層函數(shù)的作用域中查找,如果找不到就會向上查找,直到找到該變量或者到達全局作用域。
作用域鏈的形成是由函數(shù)的嵌套關系決定的。每當一個函數(shù)被創(chuàng)建時,它會保存一個對其父函數(shù)作用域的引用。當在函數(shù)內部訪問一個變量時,如果在當前函數(shù)的作用域中找不到該變量,JavaScript引擎會通過這個引用繼續(xù)向上查找,直到找到該變量或者到達全局作用域。
這種嵌套的作用域鏈關系可以形成多層嵌套,每一層都有自己的作用域。當在內層函數(shù)中訪問一個變量時,JavaScript引擎會按照作用域鏈的順序依次查找,直到找到該變量或者到達全局作用域。
需要注意的是,作用域鏈是在函數(shù)定義時確定的,而不是在函數(shù)調用時確定的。這意味著函數(shù)內部可以訪問外部函數(shù)的變量,但是外部函數(shù)不能訪問內部函數(shù)的變量。這種機制稱為詞法作用域,也是JavaScript閉包的基礎。
我認為作用域鏈的理解對于理解JavaScript中的變量作用域和閉包非常重要,它決定了變量的可見性和生命周期。
?
?
四,?什么是同源策略?為什么會產生跨域的問題?
答:
同源策略:指的是瀏覽器的一種機制,只允許在同源,也就是同協(xié)議,同域名,同端口的情況下才能進行數(shù)據(jù)交互。
我們在開發(fā)項目的過程中,往往一個項目的接口不止一個域,所以就需要進行跨域處理。這也就是跨域問題產生的由來
?
五,?常見的跨域方式有哪些?
答:
① JSONP(JSON with Padding):主要依賴的是script標簽不受同源策略的影響,src指向某一個接口的地址,同步需要傳遞callback回調函數(shù)名字,這樣當接口調用成功后,本地創(chuàng)建的全局回調函數(shù)就會執(zhí)行,且接收到數(shù)據(jù)。
?
② CORS(Cross-Origin Resource Sharing):在服務器端設置響應頭部,允許指定的域名訪問資源。前端發(fā)送請求時,瀏覽器會自動在請求頭中添加Origin字段,服務器根據(jù)該字段判斷是否允許跨域訪問。(Access-Control-Allow-origin:‘指定的ip地址’)
?
③ 代理服務器:前端通過向同域名下的代理服務器發(fā)送請求,由代理服務器轉發(fā)請求到目標服務器,再將響應數(shù)據(jù)返回給前端。這種方式需要在服務器端配置代理服務器。(服務器之間沒有跨域限制)
?
六,?說說你對閉包的理解?閉包使用的場景有哪些?
答:
閉包:是指一個函數(shù)可以訪問并操作其外部函數(shù)的變量,即使外部函數(shù)已經執(zhí)行完畢。原理就是通過將內部函數(shù)返回,從而使得內部函數(shù)可以繼續(xù)訪問外部函數(shù)的變量。
閉包常見的使用場景有如下3點:
① 保護變量:通過閉包可以將變量封裝在函數(shù)內部,避免全局污染,提高代碼的安全性。
② 延長變量的生命周期:當外部函數(shù)執(zhí)行完畢后,內部函數(shù)仍然可以訪問外部函數(shù)的變量,可以用于保存狀態(tài)或者緩存數(shù)據(jù)。
③ 實現(xiàn)函數(shù)工廠:通過閉包可以動態(tài)生成函數(shù),根據(jù)不同的參數(shù)生成不同的函數(shù)。
?
?在使用閉包函數(shù)的過程中,應當注意以下3點
④ 內存泄漏:由于閉包會保留外部函數(shù)的變量,如果閉包沒有被及時釋放,可能會導致內存泄漏問題。因此,在不需要使用閉包時,應該手動解除對閉包的引用。
⑤ 變量共享:閉包中的變量是共享的,如果閉包中的變量被修改,會影響到其他使用該變量的地方。因此,在使用閉包時需要注意變量的修改。
⑥ 性能問題:閉包會占用更多的內存,因為它需要保留外部函數(shù)的變量。在使用閉包時需要權衡內存占用和代碼的可讀性。
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?