最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【直接收藏】前端JavaScript面試100問(中)

2023-07-28 10:13 作者:千鋒前端  | 我要投稿

31、http 的理解 ? ?

HTTP 協(xié)議是超文本傳輸協(xié)議,是客戶端瀏覽器或其他程序“請求”與 Web 服務(wù)器響應(yīng)之間的應(yīng)用層通信協(xié)議。

HTTPS主要是由HTTP+SSL構(gòu)建的可進行加密傳輸、身份認(rèn)證的一種安全通信通道。

32、http 和 https 的區(qū)別 ?

  • 1、https協(xié)議需要到ca申請證書,一般免費證書較少,因而需要一定費用。

  • 2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。

  • 3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。

  • 4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。

33、git 的常用指令有哪些 ?

git?branch 分支查看

git?branch branch_1 增加分支

git?checkout branch 分支切換

git?merge branch_1 合并分支(合并前要切換當(dāng)前分支至master)

git?branch?-d?branch_1 刪除分支

git?remote 查看當(dāng)前倉庫管理的遠程倉庫信息

git?remote show origin 查看指定的遠程倉庫的詳細信息

git?push?--set-upstream?origin branch_1 第一次將本地分支推到遠程倉庫

git?push <遠程主機名> <本地分支名>:<遠程分支名> 將本地分支推到遠程分支

git?pull <遠程主機名> <遠程分支>:<本地分支> 將遠程分支拉到本地分支

git?branch?-d?branch_0 刪除本地合并后分支

git?brench?-D?branch_0 刪除本地未合并分支

it push origin?--delete?branch_0 刪除遠程分支

git?restore [filename] 進行清除工作區(qū)的改變

git?tag 查看標(biāo)簽

git?tag v1.0.0 打標(biāo)簽

git?push origin v1.0.0 將tag同步到遠程服務(wù)器

34、平時是使用 git 指令還是圖形化工具 ? ?

repository:git庫相關(guān)操作,基本意思就是字面意思。

  • 1)資源管理器中瀏覽該Git庫工作空間文件,省去查找路徑不斷點擊鼠標(biāo)的操作。

  • 2)啟動Git bash工具(命令行工具)。

  • 3)查看當(dāng)前分支文件狀態(tài),不包括未提交的信息。

  • 4)查看某個分支的文件(彈出框中可選擇需要查看的版本、分支或標(biāo)簽),跟上一條差不多,用的比較少,可能是沒有這方面的額需求。

  • 5)可視化當(dāng)前分支歷史、可視化所有分支歷史:彈出分支操作歷史,也就是gitk工具,放到gitk工具中介紹。

  • edit:用于操作commit時操作信息輸入,只能操作文字輸入部分,你沒有看錯。常用的快捷鍵大家都知道,何必要單獨做成基本沒啥用的。本來以為對變更的文件進行批量操作、本來以為可以對未版本跟蹤的文件批量刪除、本來、、、,都說了是本來。

  • Branch:新建分支(需要選擇其實版本,可以根據(jù)版本號、其他分支或標(biāo)簽來選擇)、檢出分支(覺得切換分支更合適)、重命名分支、刪除分支、當(dāng)前分支Reset操作(會丟棄所有未提交的變更,包括工作區(qū)和索引區(qū),當(dāng)然了,有彈出框提示危險操作)。

35、Promsie.all() 使用過嗎, 它是怎么使用的 ?

? promise.all()用于一個異步操作需要在幾個異步操作完成后再進行時使用。

? promise.all()接受一個promise對象組成的數(shù)組參數(shù),返回promise對象。

? 當(dāng)數(shù)組中所有promise都完成了,就執(zhí)行當(dāng)前promise對象的then方法,如果數(shù)組中有一個promise執(zhí)行失敗了,就執(zhí)行當(dāng)前promise對象的catch方法。

36、什么是三次握手和四次揮手 ?

? 三次握手是網(wǎng)絡(luò)客戶端跟網(wǎng)絡(luò)服務(wù)器之間建立連接,并進行通信的過程。相當(dāng)于客戶端和服務(wù)器之間你來我往的3個步驟。

  • 第一次握手是建立連接,客戶端發(fā)送連接請求報文,并傳送規(guī)定的數(shù)據(jù)包;

  • 第二次握手是服務(wù)器端表示接收到連接請求報文,并回傳規(guī)定的數(shù)據(jù)包;

  • 第三次握手是客戶端接收到服務(wù)器回傳的數(shù)據(jù)包后,給服務(wù)器端再次發(fā)送數(shù)據(jù)包。這樣就完成了客戶端跟服務(wù)器的連接和數(shù)據(jù)傳送。

? 四次揮手表示當(dāng)前這次連接請求已經(jīng)結(jié)束,要斷開這次連接。

  • 第一次揮手是客戶端對服務(wù)器發(fā)起斷開請求,

  • 第二次握手是服務(wù)器表示收到這次斷開請求,

  • 第三次握手是服務(wù)器表示已經(jīng)斷開連接

  • 第四次握手是客戶端斷開連接。

37、for in 和 for of 循環(huán)的區(qū)別 ?

??`for in`?用于遍歷對象的鍵(`key`),`for in`會遍歷所有自身的和原型鏈上的可枚舉屬性。如果是數(shù)組,for?in會將數(shù)組的索引(index)當(dāng)做對象的key來遍歷,其他的object也是一樣的。??`for of`是`es6`引入的語法,用于遍歷 所有迭代器iterator,其中包括`HTMLCollection`,`NodeList`,`Array`,`Map`,`Set`,`String`,`TypedArray`,`arguments`等對象的值(`item`)。

38、async/await 怎么拋出錯誤異常 ?

如果可能出錯的代碼比較少的時候可以使用try/catch結(jié)構(gòu)來了處理,如果可能出錯的代碼比較多的時候,可以利用async函數(shù)返回一個promise對象的原理來處理,給async修飾的函數(shù)調(diào)用后返回的promise對象,調(diào)用catch方法來處理異常。

39、 函數(shù)式編程和命令式編程的區(qū)別 ?

  • 命令式編程(過程式編程) :

? 專注于”如何去做”,這樣不管”做什么”,都會按照你的命令去做。解決某一問題的具體算法實現(xiàn)。

  • 函數(shù)式編程:把運算過程盡量寫成一系列嵌套的函數(shù)調(diào)用。

? ? 函數(shù)式編程強調(diào)沒有”副作用”,意味著函數(shù)要保持獨立,所有功能就是返回一個新的值,沒有其他行為,尤其是不得修改外部變量的值。
? ? 所謂”副作用”,指的是函數(shù)內(nèi)部與外部交互(最典型的情況,就是修改全局變量的值),產(chǎn)生運算以外的其他結(jié)果。

40、http 常見的響應(yīng)狀態(tài)碼 ?

??100——客戶必須繼續(xù)發(fā)出請求
??101——客戶要求服務(wù)器根據(jù)請求轉(zhuǎn)換HTTP協(xié)議版本
??200——交易成功
??201——提示知道新文件的URL
??202——接受和處理、但處理未完成
??203——返回信息不確定或不完整
??204——請求收到,但返回信息為空
??205——服務(wù)器完成了請求,用戶代理必須復(fù)位當(dāng)前已經(jīng)瀏覽過的文件
??206——服務(wù)器已經(jīng)完成了部分用戶的GET請求
??300——請求的資源可在多處得到
??301——刪除請求數(shù)據(jù)
??302——在其他地址發(fā)現(xiàn)了請求數(shù)據(jù)
??303——建議客戶訪問其他URL或訪問方式
??304——客戶端已經(jīng)執(zhí)行了GET,但文件未變化
??305——請求的資源必須從服務(wù)器指定的地址得到
??306——前一版本HTTP中使用的代碼,現(xiàn)行版本中不再使用
??307——申明請求的資源臨時性刪除
??400——錯誤請求,如語法錯誤
??401——請求授權(quán)失敗
??402——保留有效ChargeTo頭響應(yīng)
??403——請求不允許
??404——沒有發(fā)現(xiàn)文件、查詢或URl
??405——用戶在Request-Line字段定義的方法不允許
??406——根據(jù)用戶發(fā)送的Accept拖,請求資源不可訪問
??407——類似401,用戶必須首先在代理服務(wù)器上得到授權(quán)
??408——客戶端沒有在用戶指定的餓時間內(nèi)完成請求
??409——對當(dāng)前資源狀態(tài),請求不能完成
??410——服務(wù)器上不再有此資源且無進一步的參考地址
??411——服務(wù)器拒絕用戶定義的Content-Length屬性請求
??412——一個或多個請求頭字段在當(dāng)前請求中錯誤
??413——請求的資源大于服務(wù)器允許的大小
??414——請求的資源URL長于服務(wù)器允許的長度
??415——請求資源不支持請求項目格式
??416——請求中包含Range請求頭字段,在當(dāng)前請求資源范圍內(nèi)沒有range指示值,請求也不包含If-Range請求頭字段
??417——服務(wù)器不滿足請求Expect頭字段指定的期望值,如果是代理服務(wù)器,可能是下一級服務(wù)器不能滿足請求
??500——服務(wù)器產(chǎn)生內(nèi)部錯誤
??501——服務(wù)器不支持請求的函數(shù)
??502——服務(wù)器暫時不可用,有時是為了防止發(fā)生系統(tǒng)過載
??503——服務(wù)器過載或暫停維修
??504——關(guān)口過載,服務(wù)器使用另一個關(guān)口或服務(wù)來響應(yīng)用戶,等待時間設(shè)定值較長
??505——服務(wù)器不支持或拒絕支請求頭中指定的HTTP版本

41、 什么是事件流以及事件流的傳播機制 ?

? 事件觸發(fā)后,從開始找目標(biāo)元素,然后執(zhí)行目標(biāo)元素的事件,再到離開目標(biāo)元素的整個過程稱之為事件流。

? W3C標(biāo)準(zhǔn)瀏覽器事件流的傳播分為3個階段:捕獲階段、目標(biāo)階段、冒泡階段

  • 捕獲階段指找目標(biāo)元素的過程,這個找的過程,是從最大的document對象到html,再到body,。。。直到目標(biāo)元素。

  • 找到目標(biāo)元素后,調(diào)用執(zhí)行他綁定事件時對應(yīng)的處理函數(shù),這個過程被稱之為目標(biāo)階段。

  • 當(dāng)目標(biāo)元素的事件執(zhí)行結(jié)束后,再從目標(biāo)元素,到他的父元素。。。body、html再到document的過程,是冒泡階段。

42、模塊化語法 ? commonJS AMD CMD ES6 Module

  • commonJS是nodejs自帶的一種模塊化語法,將一個文件看做是一個模塊,可以將文件中導(dǎo)出的時候,被另一個文件導(dǎo)入使用。導(dǎo)出使用:module.exports導(dǎo)出。導(dǎo)入使用:require函數(shù)導(dǎo)入。

  • AMD是社區(qū)開發(fā)的模塊化語法,需要依賴require.js實現(xiàn),分為定義模塊,導(dǎo)出數(shù)據(jù)和導(dǎo)入模塊,使用數(shù)據(jù)。AMD語法的導(dǎo)入是依賴前置的,也就是說,需要用到的文件需要在第一次打開頁面全部加載完成,造成的后果就是首屏加載很慢,后續(xù)操作會很流暢。

  • CMD是玉伯開發(fā)的模塊化語法,需要依賴sea.js實現(xiàn),也分為模塊定義導(dǎo)出,和模塊導(dǎo)入使用數(shù)據(jù)。CMD語法可以依賴前置,也可以按需導(dǎo)入,緩解了AMD語法的依賴前置。

  • ES6的模塊化語法,類似于commonJS的語法,分為數(shù)據(jù)導(dǎo)出和數(shù)據(jù)導(dǎo)入,導(dǎo)入導(dǎo)出更加靈活。

43、 什么是懶加載和預(yù)加載 ?

  • 懶加載:懶加載也叫延遲加載,延遲加載網(wǎng)絡(luò)資源或符合某些條件時才加載資源。常見的就是圖片延時加載。懶加載的意義:懶加載的主要目的是作為服務(wù)器前端的優(yōu)化,減少請求數(shù)或延遲請求數(shù)。懶惰實現(xiàn)方式:

    • 1.第一種是純粹的延遲加載,使用setTimeOut或setInterval進行加載延遲.

    • 2.第二種是條件加載,符合某些條件,或觸發(fā)了某些事件才開始異步下載。

    • 3.第三種是可視區(qū)加載,即僅加載用戶可以看到的區(qū)域,這個主要由監(jiān)控滾動條來實現(xiàn),一般會在距用戶看到某圖片前一定距離便開始加載,這樣能保證用戶拉下時正好能看到圖片。

  • 預(yù)加載:提前加載圖片,當(dāng)用戶需要查看時可直接從本地緩存中渲染。

? 兩者的行為是相反的,一個是提前加載,一個是遲緩甚至不加載。懶加載對服務(wù)器前端有一定的緩解壓力作用,預(yù)加載則會增加服務(wù)器前端壓力。預(yù)加載應(yīng)用如廣告彈窗等。

44、token 一般存放在哪里 ? 為什么不存放在 cookie 內(nèi) ?

token一般放在本地存儲中。token的存在本身只關(guān)心請求的安全性,而不關(guān)心token本身的安全,因為token是服務(wù)器端生成的,可以理解為一種加密技術(shù)。但如果存在cookie內(nèi)的話,瀏覽器的請求默認(rèn)會自動在請求頭中攜帶cookie,所以容易受到csrf攻擊。

45、 less 和 sass 的區(qū)別 ?

  • 編譯環(huán)境不一樣,sass是服務(wù)器端處理的,可以用Ruby、node-sass來編譯;less需要引入less.js來處理輸出,也可以使用工具在服務(wù)器端處理成css,也有在線編譯的。

  • 變量定義符不一樣,less用的是@,而sass用$。

  • sass支持分支語句,less不支持

44、瀏覽器的同源策略機制 ?

同源策略,又稱SOP,全稱Same Origin Policy,是瀏覽器最基本的安全功能。站在瀏覽器的較短看網(wǎng)頁,如果網(wǎng)絡(luò)上的接口可以不受限制、無需授權(quán)隨意被人調(diào)用,那將是一個非常嚴(yán)重的混亂場景。瀏覽器為了安全有序,內(nèi)部實現(xiàn)了同源策略。

同源策略,指的是瀏覽器限制當(dāng)前網(wǎng)頁只能訪問同源的接口資源。

所謂同源,指當(dāng)前頁面和請求的接口,兩方必須是同協(xié)議、且同域名、且同端口。只要有一個不相同,則會受到瀏覽器約束,不允許請求。

但當(dāng)一個項目變的很大的時候,將所有內(nèi)容放在一個網(wǎng)站或一個服務(wù)器中會讓網(wǎng)站變的臃腫且性能低下,所以,在一些場景中,我們需要跨過同源策略,請求到不同源的接口資源,這種場景叫跨域。

跨域大致有3種方案:

  • jsonp

    這種方式是利用瀏覽器不限制某些標(biāo)簽發(fā)送跨域請求,例如link、img、iframe、script。通常請求請求回來的資源要在js中進行處理,所以jsonp跨域是利用script標(biāo)簽進行發(fā)送,且這種請求方式只能是get請求。

  • cors

    這種方式是讓接口資源方面進行授權(quán),授權(quán)允許訪問。在接口資源處添加響應(yīng)頭即可通過瀏覽器的同源策略,響應(yīng)頭具體的鍵值對如下:

    {Access-Control-Allow-Origin:?'*'}


  • proxy

    這種方式屬于找外援的一種方式,瀏覽器只能限制當(dāng)前正在打開的web頁面發(fā)送請求,但無法限制服務(wù)器端請求接口資源。所以我們可以將請求發(fā)送到自己服務(wù)器,然后自己服務(wù)器去請求目標(biāo)接口資源,最后自己服務(wù)器將接口資源返回給當(dāng)前頁面,類似于找外援代替自己請求目標(biāo)接口資源。

    這種方式通常要對服務(wù)器進行代理配置,需要對apache服務(wù)器、nginx服務(wù)器、nodejs服務(wù)器進行配置。

45、 瀏覽器的緩存有哪些 ? 什么時候使用強制緩存 ? 什么時候使用協(xié)商緩存 ?

當(dāng)我們訪問同一個頁面時,請求資源、數(shù)據(jù)都是需要一定的耗時,如果可以將一些資源緩存下來,那么從第二次訪問開始,就可以減少加載時間,提高用戶體驗,也能減輕服務(wù)器的壓力。

瀏覽器緩存分為強緩存和協(xié)商緩存,當(dāng)存在緩存時,客戶端第一次向服務(wù)器請求數(shù)據(jù)時,客戶端會緩存到內(nèi)存或者硬盤當(dāng)中,當(dāng)?shù)诙潍@取相同的資源,強緩存和協(xié)商緩存的應(yīng)對方式有所不同。

強緩存:當(dāng)客戶端第二次向服務(wù)器請求相同的資源時,不會向服務(wù)器發(fā)送請求,而是直接從內(nèi)存/硬盤中間讀取。緩存由服務(wù)器的響應(yīng)頭里 cache-control 和 expires 兩個字段決定

協(xié)商緩存:當(dāng)客戶端第二次向服務(wù)器請求相同的資源時,先向服務(wù)器發(fā)送請求"詢問"該請求的文件緩存在ben'd與服務(wù)器相比是否更改,如果更改,則更新文件,如果沒有就從內(nèi)存/硬盤中讀取。協(xié)商緩存由 last-modified 和 etag兩個字段決定

46、 數(shù)組方法 forEach 和 map 的區(qū)別 ?

forEach和map都是循環(huán)遍歷數(shù)組中的每一項。forEach() 和 map() 里面每一次執(zhí)行匿名函數(shù)都支持3個參數(shù):數(shù)組中的當(dāng)前項item,當(dāng)前項的索引index,原始數(shù)組input。匿名函數(shù)中的this都是指Window。只能遍歷數(shù)組。

他們的區(qū)別是:forEach沒有返回值,但map中要有返回值,返回處理后的所有新元素組成的數(shù)組。

47、 什么是函數(shù)作用域 ? 什么是作用域鏈 ?

作用域就是在代碼執(zhí)行過程中,形成一個獨立的空間,讓空間內(nèi)的變量不會泄露在空間外,也讓獨立空間內(nèi)的變量函數(shù)在獨立空間內(nèi)運行,而不會影響到外部的環(huán)境。

作用域分為全局作用域和局部作用域,也就是本來有一個巨大的空間,空間內(nèi)定義的函數(shù)內(nèi)部,就形成了一個獨立的小空間,全局作用域是最大的作用域。

但是當(dāng)獨立空間內(nèi)的數(shù)據(jù)不能滿足需求時,是可以從外部獲取數(shù)據(jù)的,也就是說這樣的獨立空間之間是可以有層級關(guān)系的,外部的空間不可以從內(nèi)部的空間獲取數(shù)據(jù),但內(nèi)部的空間可以。當(dāng)子級空間在父級空間中獲取數(shù)據(jù)的時,父級空間沒有的話,父級空間也會到他的父級空間中查找數(shù)據(jù),這樣形成的鏈?zhǔn)浇Y(jié)構(gòu)叫作用域鏈。

當(dāng)將一個變量當(dāng)做值使用時,會先在當(dāng)前作用域中查找這個變量的定義和數(shù)據(jù),如果沒有定義的話,就會去父級作用域中查找,如果父級作用域中有的話就使用這個值,如果父級作用域中也沒有的話,就通過父級作用域查找他的父級作用域,直到找到最大的作用域-全局,如果全局也沒有就報錯。

當(dāng)將一個變量當(dāng)做數(shù)據(jù)容器存儲,也就是給變量賦值的時候,也要先在自己作用域中查找變量的定義,如果沒有就在上一級作用域中查找,直到全局,如果全局作用域中也沒有這個變量的定義,就在全局定義這個變量并賦值。

48、 ES6 中 Set 和 Map 的原理 ?

Set 是無重復(fù)值的有序列表。根據(jù) `Object.is()`方法來判斷其中的值不相等,以保證無重復(fù)。Set 會自動移除重復(fù)的值,因此你可以使用它來過濾數(shù)組中的重復(fù)值并返回結(jié)果。Set并不是數(shù)組的子類型,所以你無法隨機訪問其中的值。但你可以使用`has()` 方法來判斷某個值是否存在于 Set 中,或通過 `size` 屬性來查看其中有多少個值。Set 類型還擁有`forEach()`方法,用于處理每個值

Map 是有序的鍵值對,其中的鍵允許是任何類型。與 Set 相似,通過調(diào)用 `Object.is()`方法來判斷重復(fù)的鍵,這意味著能將數(shù)值 5 與字符串 "5" 作為兩個相對獨立的鍵。使用`set()` 方法能將任何類型的值關(guān)聯(lián)到某個鍵上,并且該值此后能用 `get()` 方法提取出來。Map 也擁有一個 `size` 屬性與一個 `forEach()` 方法,讓項目訪問更容易。

49、 0.1 + 0.2 為什么不等于 0.3, 在項目中遇到要怎么處理 ?

計算機內(nèi)部存儲數(shù)據(jù)使用2進制存儲,兩個數(shù)字進行的數(shù)學(xué)運算,首先是將這兩個數(shù)字以2進制形式,存儲在計算機內(nèi)部,然后在計算機內(nèi)部使用兩個2進制數(shù)字進行計算,最后將計算結(jié)果的2進制數(shù)字轉(zhuǎn)為10進制展示出來。

由于10進制的小數(shù)在轉(zhuǎn)2進制的時候,規(guī)則是小數(shù)部分乘以2,判斷是否得到一個整數(shù),如果得到整數(shù),轉(zhuǎn)換完成;如果沒有得到整數(shù),則繼續(xù)乘以2判斷。所以,0.1和0.2在轉(zhuǎn)換2進制的時候,其實是一個無限死循環(huán),也就是一直乘以2沒有得到整數(shù)的時候,但計算機內(nèi)部對于無限死循環(huán)的數(shù)據(jù),會根據(jù)一個標(biāo)準(zhǔn)保留52位。也就是說,計算機內(nèi)部在存儲0.1和0.2的時候,本來就不精準(zhǔn),兩個不精準(zhǔn)的小數(shù)在計算后,距離精準(zhǔn)的結(jié)果是有一定誤差的。

項目中碰到這種情況,有3種處理方法:

  • 將小數(shù)乘以10的倍數(shù),轉(zhuǎn)為整數(shù),然后計算,計算完成后,再縮小10的倍數(shù),例如:

  • 使用數(shù)字的toFixed方法,強制保留小數(shù)點后多少位,例

  • 自定義數(shù)字運算方法,當(dāng)需要進行數(shù)學(xué)運算的時候,不直接進行,調(diào)用自定義的方法進行,例:(加法封裝)

50、 什么是模塊化思想 ?

就是JS中將不同功能的代碼封裝在不同的文件中, 互相引用時不會發(fā)生命名沖突的一種思想, 大多數(shù)情況下, 一個文件就是一個模塊

模塊化的實現(xiàn),有多種方案:

  • CommonJS:

    CommonJSnodejs中使用的模塊化規(guī)范在 nodejs 應(yīng)用中每個文件就是一個模塊,擁有自己的作用域,文件中的變量、函數(shù)都是私有的,與其他文件相隔離。模塊導(dǎo)出:module.exports=數(shù)據(jù),模塊導(dǎo)入:require('模塊文件路徑')

  • ES6的模塊化:

    模塊功能主要由兩個命令構(gòu)成:exportimport。export命令用于規(guī)定模塊的對外接口,import命令用于輸入其他模塊提供的功能。

    一個模塊就是一個獨立的文件。該文件內(nèi)部的所有變量,外部無法獲取。如果你希望外部能夠讀取模塊內(nèi)部的某個變量,就必須使用export關(guān)鍵字輸出該變量。下面是一個 JS 文件,里面使用export命令輸出變量。

  • AMD (Asynchronous Module Definition):

    特點: 提倡依賴前置,在定義模塊的時候就要聲明其依賴的模塊:導(dǎo)入模塊require([module],callback);定義模塊:define('模塊名稱', 函數(shù))。

  • CMD (Common Module Definition):

    CMD規(guī)范是國內(nèi)SeaJS的推廣過程中產(chǎn)生的。提倡就近依賴(按需加載),在用到某個模塊的時候再去require。定義模塊:define(function (require, exports, module) {}),使用模塊:seajs.use()

51、 說說怎么用js 寫無縫輪播圖

將所有需要輪播的內(nèi)容動態(tài)復(fù)制一份,放在原本的容器中,加定時器讓整個容器中的內(nèi)容滾動輪播,當(dāng)內(nèi)容輪播到left值為-原本的內(nèi)容寬度時,快速將內(nèi)容切換到left值為0的狀態(tài)。

52、 JS 如何實現(xiàn)多線程 ?

我們都知道JS是一種單線程語言,即使是一些異步的事件也是在JS的主線程上運行的(具體是怎么運行的,可以看我另一篇博客JS代碼運行機制)。像setTimeout、ajax的異步請求,或者是dom元素的一些事件,都是在JS主線程執(zhí)行的,這些操作并沒有在瀏覽器中開辟新的線程去執(zhí)行,而是當(dāng)這些異步操作被操作時或者是被觸發(fā)時才進入事件隊列,然后在JS主線程中開始運行。

首先說一下瀏覽器的線程,瀏覽器中主要的線程包括,UI渲染線程,JS主線程,GUI事件觸發(fā)線程,http請求線程。

JS作為腳本語言,它的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題。(這里這些問題我們不做研究)

但是單線程的語言,有一個很致命的確定。如果說一個腳本語言在執(zhí)行時,其中某一塊的功能在執(zhí)行時耗費了大量的時間,那么就會造成阻塞。這樣的項目,用戶體驗是非常差的,所以這種現(xiàn)象在項目的開發(fā)過程中是不允許存在的。

其實JS為我們提供了一個Worker的類,它的作用就是為了解決這種阻塞的現(xiàn)象。當(dāng)我們使用這個類的時候,它就會向瀏覽器申請一個新的線程。這個線程就用來單獨執(zhí)行一個js文件。? var worker?=?new Worker(js文件路徑);那么這個語句就會申請一個線程用來執(zhí)行這個js文件。這樣也就實現(xiàn)了js的多線程。

53、 閉包的使用場景 ?

一個函數(shù)被當(dāng)作值返回時,也就相當(dāng)于返回了一個通道,這個通道可以訪問這個函數(shù)詞法作用域中的變量,即函數(shù)所需要的數(shù)據(jù)結(jié)構(gòu)保存了下來,數(shù)據(jù)結(jié)構(gòu)中的值在外層函數(shù)執(zhí)行時創(chuàng)建,外層函數(shù)執(zhí)行完畢時理因銷毀,但由于內(nèi)部函數(shù)作為值返回出去,這些值得以保存下來。而且無法直接訪問,必須通過返回的函數(shù)。這也就是私有性。

本來執(zhí)行過程和詞法作用域是封閉的,這種返回的函數(shù)就好比是一個蟲洞,開了掛。

閉包的形成很簡單,在執(zhí)行過程完畢后,返回函數(shù),或者將函數(shù)得以保留下來,即形成閉包。

  • 防抖:

  • 節(jié)流:

  • 迭代器:

  • 緩存:

  • getter和setter:

  • 柯里化:

  • 循環(huán)中綁定事件或執(zhí)行異步代碼

  • 單例模式:

54、 常見的兼容問題有哪些 ?

  • 獲取標(biāo)簽節(jié)點:

    document.getElementsByClassName('類名')在低版本ie中不兼容。解決方法是使用其他方式獲?。?/p>

獲取卷去的高度

?解決辦法使用兼容寫法:

獲取樣式

使用函數(shù)封裝的方式兼容:

事件偵聽器

使用函數(shù)封裝的方式解決:

事件解綁

使用函數(shù)封裝的方式解決:

事件對象的獲取

使用短路運算符解決:

阻止默認(rèn)行為

通過封裝函數(shù)解決

阻止事件冒泡

通過函數(shù)封裝解決:

獲取精準(zhǔn)的目標(biāo)元素

通過短路運算符解決:

獲取鍵盤碼

通過短路運算符解決:

55、 在 JS 中如何阻止事件冒泡 ?

使用事件對象阻止事件冒泡,以前的w3c瀏覽器中,使用事件對象的方法阻止:

? 事件對象.stopPropagation()

在ie低版本瀏覽器中,使用事件對象的屬性阻止:

? 事件對象.cancelBubble?=?true

現(xiàn)在的w3c瀏覽器也支持ie低版本瀏覽器中的寫法,所以以前在阻止事件冒泡的時候,需要考慮兼容寫法,現(xiàn)在就不需要了,直接用ie低版本瀏覽器中的寫法即可。

56、兩個數(shù)組 var A = [1, 5, 6]; var B = [2, 6, 7],實現(xiàn)一個方法,找出僅存在于A 或者 僅 存在于B中的所有數(shù)字。


57、 你了解構(gòu)造函數(shù)嗎 ? class 是什么 ? 兩者有什么區(qū)別 ?


在es5中構(gòu)造函數(shù)其實就是在定義一個類,可以實例化對象,es6中class其實是構(gòu)造函數(shù)的語法糖。但還是有點區(qū)別的:

  • 在class內(nèi)部和class的方法內(nèi)部,默認(rèn)使用嚴(yán)格模式

  • class類不存在預(yù)解析,也就是不能先調(diào)用class生成實例,再定義class類,但是構(gòu)造函數(shù)可以。

  • class中定義的方法默認(rèn)不能被枚舉,也就是不能被遍歷。

  • class必須使用new執(zhí)行,但是構(gòu)造函數(shù)沒有new也可以執(zhí)行。

  • class中的所有方法都沒有原型,也就不能被new

  • class中繼承可以繼承靜態(tài)方法,但是構(gòu)造函數(shù)的繼承不能。

58、是否存在a的值(a==0 && a==1)為true 的情況 ?

59、for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); } 要求:輸出0,1,2,3,4

首先這個面試題考察的是對于js中異步代碼以及作用域的理解:

js中常見的異步代碼包括定時器和ajax。js執(zhí)行代碼的流程是碰到同步代碼就執(zhí)行,碰到異步就交給瀏覽器的webAPI處理,當(dāng)webAPI中的異步該執(zhí)行時,webAPI會將需要執(zhí)行的回調(diào)函數(shù)放在任務(wù)隊列中,等候執(zhí)行,所以,js中所有的異步代碼總會在所有同步代碼執(zhí)行結(jié)束后,再執(zhí)行任務(wù)隊列中的代碼。

在這個問題中,循環(huán)是同步代碼,定時器是異步代碼,所以整個循環(huán)都執(zhí)行結(jié)束以后才會執(zhí)行定時器代碼。

for循環(huán)中使用var定義的變量是全局變量,定時器回調(diào)函數(shù)中輸出變量的時候,根據(jù)作用域規(guī)則,先在當(dāng)前作用域中變量i的定義表達式,如果沒有找到,就去上一級作用域中找,此時,在局部作用域中沒有找到,去上級作用域中,也就是全局找到了,全局中的i,因為循環(huán)已經(jīng)執(zhí)行結(jié)束了,所以i的值是5。

最終,會輸出5個5。

其次考察的是對于類似問題的解決方式,間接性判斷你是否有過類似情況的開發(fā):

這個問題的解決思路就是讓回調(diào)函數(shù)中輸出i的時候,不要去全局中找i,因為全局的i在循環(huán)執(zhí)行結(jié)束后已經(jīng)變成5了,根據(jù)這個思路,有2種解決辦法:

  • 在異步代碼外面嵌套一層函數(shù)作用域

原理是自調(diào)用函數(shù)會產(chǎn)生作用域,循環(huán)5次就會產(chǎn)生5個作用域,每個作用域代碼在執(zhí)行的時候都有形參i傳遞。所以每個作用域中的i都是不同的,分別是:0 1 2 3 4。當(dāng)作用域中的異步代碼執(zhí)行的時候,自己作用域中沒有i變量的定義,然后上級作用域就是自調(diào)用函數(shù)的作用域,找到了單獨的i。最終可以輸出:0 1 2 3 4

  1. 將循環(huán)代碼中的var換成es6的let

es6的let自帶塊級作用域,原理跟第一種解決思路是一樣的,轉(zhuǎn)成es5后,代碼是一樣的。

60、實現(xiàn)一個 add 方法 使計算結(jié)果能夠滿足如下預(yù)期:?- add(1)(2)(3)() = 6 - add(1,2,3)(4)() = 10







【直接收藏】前端JavaScript面試100問(中)的評論 (共 條)

分享到微博請遵守國家法律
资溪县| 江津市| 尖扎县| 临湘市| 启东市| 万源市| 星座| 汉中市| 通河县| 西峡县| 和田县| 乌拉特中旗| 定安县| 大厂| 大港区| 屏东县| 麻阳| 黔东| 龙泉市| 定南县| 南城县| 永胜县| 玛纳斯县| 隆林| 汉中市| 石楼县| 南郑县| 武山县| 通渭县| 榆中县| 吴旗县| 昌吉市| 龙里县| 常宁市| 含山县| 广灵县| 封开县| 土默特左旗| 兴隆县| 长丰县| 滦平县|