前端知識(shí)點(diǎn)(前端小知識(shí)點(diǎn)總結(jié))
需要了解的前端知識(shí)可以說是包羅萬象。而且深入挖掘某個(gè)知識(shí)點(diǎn)是很辛苦的。最近忙著面試,也看了很多面試指南。下面是我認(rèn)為值得一讀的前端知識(shí)。
以及HTML和CSS部分。
瀏覽器內(nèi)核:瀏覽器內(nèi)核是瀏覽器的核心,也叫“渲染引擎”,用來解釋網(wǎng)頁(yè)的語法并渲染到網(wǎng)頁(yè)上。瀏覽器的內(nèi)核決定了瀏覽器應(yīng)該如何顯示網(wǎng)頁(yè)的內(nèi)容以及頁(yè)面的格式信息。瀏覽器內(nèi)核可以分為兩部分:渲染引擎(布局工程師或渲染引擎)和JS引擎。1.IE瀏覽器內(nèi)核:三叉戟內(nèi)核,又稱IE內(nèi)核;2.Chrome瀏覽器內(nèi)核:統(tǒng)稱為Chrome內(nèi)核或Chrome內(nèi)核。以前是Webkit內(nèi)核,現(xiàn)在是Blink內(nèi)核;3.火狐瀏覽器內(nèi)核:壁虎內(nèi)核,俗稱火狐內(nèi)核;4.Safari瀏覽器內(nèi)核:Webkit內(nèi)核;5.Opera瀏覽器內(nèi)核:原來是自己的Presto內(nèi)核,后來是Webkit,現(xiàn)在是Blink內(nèi)核;6、360瀏覽器、獵豹瀏覽器內(nèi)核:IE+Chrome雙內(nèi)核;7.搜狗、旅行、QQ瀏覽器內(nèi)核:Trident(兼容模式)+Webkit(高速模式);8.百度瀏覽器,世界之窗內(nèi)核:IE內(nèi)核;9、2345瀏覽器內(nèi)核:以前是IE內(nèi)核,現(xiàn)在也是IE+Chrome雙內(nèi)核;
箱式模型:標(biāo)準(zhǔn)箱式模型和IE箱式模型的區(qū)別,boder-sizing用于轉(zhuǎn)換。Flex layout繪制一個(gè)九方形網(wǎng)格
.wrap{display:flex;flex-direction:column;height:300px}.flex-box{display:flex;flex-direction:row;flex:1}.flex-item{flex:1;}先說清浮:1。將overflow:auto添加到要清除浮動(dòng)的元素中;縮放:1;2.添加a . clear { clear:both;溢出:隱藏}這部分比較基礎(chǔ),沒有問題,其次是JS部分。
Java Script語言
未定義和未定義有什么區(qū)別?
已在作用域中聲明但尚未賦值的變量是未定義的。相反,沒有在作用域中聲明的變量是未聲明的。
對(duì)于未聲明變量的引用,瀏覽器會(huì)報(bào)錯(cuò)引用,比如ReferenceError: b未定義。但是我們可以使用typeof的安全機(jī)制來避免報(bào)錯(cuò),因?yàn)閠ypeof會(huì)為未定義(或未定義)的變量返回“undefined”。
{}和[]的valueOf和toString的結(jié)果是什么?
{}的結(jié)果值為{},toString的結(jié)果為“[object object]”[],toString的結(jié)果為“”
說到這里,我應(yīng)該擴(kuò)展一下原型鏈:
當(dāng)我們?cè)L問一個(gè)對(duì)象和屬性時(shí),如果這個(gè)屬性在對(duì)象內(nèi)部不存在,它會(huì)在它的原型對(duì)象中尋找這個(gè)屬性,這個(gè)原型對(duì)象也會(huì)有自己的原型,所以它一直在尋找。來源是:Object.prototype .
獲取js原型的方法:p.proto,Object.getPrototypeOf
基于對(duì)這一點(diǎn)的理解,調(diào)用、應(yīng)用和綁定
在瀏覽器中,這指向全局范圍中的窗口對(duì)象;
在函數(shù)中,這總是指向最后調(diào)用他的對(duì)象;
在構(gòu)造函數(shù)中,這指向new出來的新對(duì)象;
這在調(diào)用、應(yīng)用和綁定中被強(qiáng)綁定到指定的對(duì)象;
這是一個(gè)特殊的箭頭函數(shù)。箭頭函數(shù)this是父作用域this,而不是調(diào)用this。要知道,前四個(gè)方法都是在調(diào)用的時(shí)候確定的,也就是動(dòng)態(tài)的,而arrow函數(shù)的this point是靜態(tài)的,聲明的時(shí)候就確定了;
Apply、call和bind是js函數(shù)中內(nèi)置的一些API。調(diào)用它們可以指定這個(gè)for函數(shù)的執(zhí)行,也可以傳遞參數(shù)。大家都知道怎么用,但是怎么理解需要注意。
關(guān)于結(jié)束
這也是關(guān)于閉包的陳詞濫調(diào)。在你不知道的JS中有介紹:= =當(dāng)一個(gè)函數(shù)能夠記住并訪問它的詞法作用域時(shí),就發(fā)生了閉包,即使這個(gè)函數(shù)是在當(dāng)前作用域之外執(zhí)行的。= =我覺得有點(diǎn)基本功的小伙伴恍然大悟。通俗地說,閉包是指一個(gè)函數(shù)可以訪問另一個(gè)函數(shù)范圍內(nèi)的變量。創(chuàng)建閉包最常見的方法是在一個(gè)函數(shù)中創(chuàng)建另一個(gè)函數(shù),創(chuàng)建的函數(shù)可以訪問當(dāng)前函數(shù)的局部變量。
function?a(){????var?n?=?0;????function?add(){???????n++;???????console.log(n);????}????return?add;}var?a1?=?a();?//注意,函數(shù)名只是一個(gè)標(biāo)識(shí)(指向函數(shù)的指針),而()才是執(zhí)行函數(shù);a1();????//1a1();????//2??第二次調(diào)用n變量還在內(nèi)存中關(guān)于事件(三種事件模型)
事件是用戶操作網(wǎng)頁(yè)或網(wǎng)頁(yè)本身的某些操作時(shí)發(fā)生的交互動(dòng)作?,F(xiàn)代瀏覽器中有三種事件模型。1.DOM level 0模型:這個(gè)模型不會(huì)傳播,所以沒有事件流的概念。但是,現(xiàn)在有些瀏覽器支持冒泡的實(shí)現(xiàn)??梢灾苯釉诰W(wǎng)頁(yè)中定義監(jiān)控功能,也可以通過js屬性指定監(jiān)控功能。這種方法與所有瀏覽器兼容。
2.IE事件模型:在這個(gè)事件模型中,一個(gè)事件有兩個(gè)過程,事件處理階段和事件冒泡階段。事件處理階段將首先執(zhí)行目標(biāo)元素綁定的監(jiān)聽事件。然后是事件冒泡階段,指的是從目標(biāo)元素到文檔的事件冒泡。依次檢查傳遞節(jié)點(diǎn)是否綁定了事件監(jiān)控函數(shù),如果是,則執(zhí)行。在該模型中,通過attachEvent添加monitor函數(shù),可以添加多個(gè)monitor函數(shù),這些函數(shù)將按順序執(zhí)行。3.DOM2事件模型:在這個(gè)事件模型中,一個(gè)事件有三個(gè)過程,第一個(gè)過程是事件捕獲階段。Capture是指事件從文檔向下傳播到目標(biāo)元素,依次檢查傳遞節(jié)點(diǎn)是否與事件監(jiān)視器函數(shù)綁定,如果是則執(zhí)行。后兩個(gè)階段與IE事件模型的階段相同。在這個(gè)事件模型中,事件綁定的函數(shù)是addEventListener,其中第三個(gè)參數(shù)可以指定事件是否在捕獲階段執(zhí)行。
DOM操作——如何添加、刪除、移動(dòng)、復(fù)制、創(chuàng)建和查找節(jié)點(diǎn)?
(1)創(chuàng)建一個(gè)新節(jié)點(diǎn)
createDocumentFragment()????//創(chuàng)建一個(gè)DOM片段createElement()???//創(chuàng)建一個(gè)具體的元素createTextNode()???//創(chuàng)建一個(gè)文本節(jié)點(diǎn)`(2)添加、刪除、替換和插入
appendChild(node)removeChild(node)replaceChild(new,old)insertBefore(new,old)(3)搜索
getElementById();getElementsByName();getElementsByTagName();getElementsByClassName();querySelector();querySelectorAll();(4)屬性操作
getAttribute(key);setAttribute(key,?value);hasAttribute(key);removeAttribute(key);js數(shù)組和對(duì)象的原生方法有哪些?列出它們。
手寫ajax
原生:
//1:創(chuàng)建XMLHttpRequest對(duì)象var?xhr?=?window.XMLHttpRequest?new?XMLHttpRequest():new?ActiveXObject("Microsoft.XMLHTTP");//?兼容IE6及以下版本//2:配置?Ajax請(qǐng)求地址xhr.open("get","index.xml",true);//3:發(fā)送請(qǐng)求xhr.send(null);?//?嚴(yán)謹(jǐn)寫法//4:監(jiān)聽請(qǐng)求,接受響應(yīng)xhr.onreadysatechange=function(){?????if(xhr.readySates==4&&xhr.status==200?||?xhr.status==304?)??????????console.log(xhr.responsetXML)}jquery:
?$.ajax({??????????type:"post",??????????url:"",??????????async:ture,//async?異步??sync??同步??????????data:data,//針對(duì)post請(qǐng)求??????????dataType:"jsonp",??????????success:function?(msg)?{??????????},??????????error:function?(error)?{??????????}????????})你對(duì)模塊化開發(fā)的理解
結(jié)合我自己的項(xiàng)目,我提了一個(gè)學(xué)長(zhǎng)的介紹:
我對(duì)模塊的理解是,模塊是實(shí)現(xiàn)特定功能的一組方法。js一開始只是實(shí)現(xiàn)了一些簡(jiǎn)單的功能,所以沒有模塊的概念。然而,隨著程序的日益復(fù)雜,代碼的模塊化開發(fā)變得越來越重要。由于函數(shù)的作用域是獨(dú)立的,原來的編寫方法是用函數(shù)做模塊,幾個(gè)函數(shù)做一個(gè)模塊,但是這種方法容易造成全局變量的污染,模塊之間沒有聯(lián)系。后來提出了對(duì)象編寫方法,將函數(shù)作為對(duì)象來實(shí)現(xiàn),解決了直接將函數(shù)作為模塊的一些缺點(diǎn),但這種方法會(huì)將模塊成員全部暴露,外部代碼可以修改內(nèi)部屬性的值。目前最常用的方法是立即執(zhí)行函數(shù),可以利用閉包實(shí)現(xiàn)模塊私有范圍的建立,同時(shí)不會(huì)污染全局范圍。
js的模塊規(guī)范
CommonJS:modlue.exports.x拋出(定義模塊的輸出接口)并要求引用它。這個(gè)模塊加載方案是一個(gè)服務(wù)器端(nodejs)解決方案。它以同步的方式引入模塊。因?yàn)榉?wù)器端的文件存儲(chǔ)在本地磁盤,讀取速度非???,所以用同步的方式加載是沒有問題的。但是如果是在瀏覽器端,因?yàn)槟K是通過網(wǎng)絡(luò)請(qǐng)求加載的,所以使用異步加載更合適。AMD:這個(gè)方案使用異步加載來加載模塊。模塊的加載不影響后續(xù)語句的執(zhí)行。所有依賴于這個(gè)模塊的語句都定義在一個(gè)回調(diào)函數(shù)中,然后在加載完成后執(zhí)行回調(diào)函數(shù)。**require.js **實(shí)現(xiàn)AMD規(guī)范。CMD:這個(gè)方案和AMD方案都是為了解決異步模塊加載的問題。sea.js實(shí)現(xiàn)了CMD規(guī)范。它和require.js的區(qū)別在于,在定義一個(gè)模塊的時(shí)候,它對(duì)依賴關(guān)系的處理是不同的,對(duì)依賴模塊的執(zhí)行時(shí)序的處理也是不同的。由ES6提出:參考上一篇博客。
(重要)js運(yùn)行機(jī)制
setTimeout(function()?{??console.log(1)},?0);new?Promise(function(resolve,?reject)?{??console.log(2);??resolve()}).then(function()?{??console.log(3)});process.nextTick(function?()?{??console.log(4)})console.log(5)結(jié)果如何呢?先想想。我先介紹一下運(yùn)行機(jī)制。
Js單線程:
JavaScript的一個(gè)特點(diǎn)是單線程,即同一時(shí)間只能做一件事。
JavaScript的單線程,這和它的用途有關(guān)。JavaScript作為一種瀏覽器腳本語言,主要用于與用戶交互和操作DOM。這就決定了只能單線程,否則會(huì)帶來復(fù)雜的同步問題。例如,假設(shè)JavaScript同時(shí)有兩個(gè)線程,一個(gè)線程向DOM節(jié)點(diǎn)添加內(nèi)容,另一個(gè)線程刪除該節(jié)點(diǎn)。瀏覽器應(yīng)該以哪個(gè)線程為標(biāo)準(zhǔn)?所以,為了避免復(fù)雜,JavaScript從誕生之日起就一直是單線程的,這也成為了這種語言的核心特征,以后也不會(huì)改變。
Js事件循環(huán)
js代碼執(zhí)行過程中會(huì)有很多任務(wù)。這些任務(wù)一般分為兩類:1 .同步任務(wù)2。異步任務(wù)。當(dāng)我們打開一個(gè)網(wǎng)站時(shí),網(wǎng)頁(yè)的渲染過程是很多同步的任務(wù),比如頁(yè)面骨架和頁(yè)面元素的渲染。然而,需要大量資源和時(shí)間的任務(wù),例如加載圖片和音樂,是異步任務(wù)。
同步任務(wù)進(jìn)入主線程,異步任務(wù)進(jìn)入事件表注冊(cè)上報(bào)。當(dāng)指定的事情完成后,事件表會(huì)將該函數(shù)移入事件隊(duì)列。主線程中的任務(wù)完成后是空,所以會(huì)去事件隊(duì)列讀取相應(yīng)的函數(shù),進(jìn)入主線程執(zhí)行。上述過程會(huì)不斷重復(fù),也就是所謂的事件循環(huán)。
異步任務(wù)還可以分為:微任務(wù)(microtask):當(dāng)執(zhí)行堆棧中的代碼執(zhí)行完畢后,它會(huì)在執(zhí)行宏任務(wù)隊(duì)列之前檢查微任務(wù)隊(duì)列中是否有任務(wù)。如果有,它會(huì)在執(zhí)行宏任務(wù)隊(duì)列之前清除微任務(wù)隊(duì)列空中的任務(wù),宏任務(wù)隊(duì)列包括Promise、nextTick、callback、Object.observe、MutationObserver。
Macrotask:等到執(zhí)行堆棧和微任務(wù)隊(duì)列結(jié)束,每個(gè)宏任務(wù)結(jié)束后,我們會(huì)檢查微任務(wù)隊(duì)列中是否有新添加的任務(wù)。如果有,我們會(huì)先清空微任務(wù)隊(duì)列空中的任務(wù),然后再繼續(xù)執(zhí)行下一個(gè)宏任務(wù),包括:腳本代碼塊,setTimeout,setInterval,I/O。
推薦面試答案:
首先,js是單線程運(yùn)行的。代碼執(zhí)行時(shí),不同函數(shù)的執(zhí)行上下文被壓入執(zhí)行棧,以保證代碼的有序執(zhí)行。
在執(zhí)行同步代碼時(shí),如果遇到異步事件,js引擎不會(huì)一直等待其返回結(jié)果,而是將事件掛起,繼續(xù)執(zhí)行執(zhí)行棧中的其他任務(wù)。
同步事件執(zhí)行后,異步事件對(duì)應(yīng)的回調(diào)被添加到不同于當(dāng)前執(zhí)行棧的另一個(gè)任務(wù)隊(duì)列中執(zhí)行。
隊(duì)列可以分為宏觀任務(wù)對(duì)列和微觀任務(wù)對(duì)列。當(dāng)當(dāng)前執(zhí)行棧中的事件結(jié)束后,js engine會(huì)先判斷微任務(wù)對(duì)列中是否有可以執(zhí)行的任務(wù),如果有,則將微任務(wù)組長(zhǎng)的事件推入棧中執(zhí)行。
當(dāng)列中的所有任務(wù)都由微任務(wù)執(zhí)行時(shí),通過宏任務(wù)判斷列中的任務(wù)。
那么對(duì)第一個(gè)題目應(yīng)該是清楚的:25431
var,let,const有什么區(qū)別?
Var聲明有變量提升,而let和const沒有。
console.log(a);?//?undefined??===>??a已聲明還沒賦值,默認(rèn)得到undefined值var?a?=?100;console.log(b);?//?報(bào)錯(cuò):b?is?not?defined??===>?找不到b這個(gè)變量let?b?=?10;console.log(c);?//?報(bào)錯(cuò):c?is?not?defined??===>?找不到c這個(gè)變量const?c?=?10;并讓const聲明形成一個(gè)塊作用域。
if(1){??var?a?=?100;??let?b?=?10;}console.log(a);?//?100console.log(b)??//?報(bào)錯(cuò):b?is?not?defined??===>?找不到b這個(gè)變量-------------------------------------------------------------if(1){??var?a?=?100;??const?c?=?1;}console.log(a);?//?100console.log(c)??//?報(bào)錯(cuò):c?is?not?defined??===>?找不到c這個(gè)變量在同一個(gè)作用域內(nèi),let和const不能聲明同名的變量,而var可以聲明的變量會(huì)掛載到窗口上,而let和const聲明的變量不會(huì)。
var?a?="lly"?console.log(window.a)//lly新操作員做了什么?
創(chuàng)建空(即{})的簡(jiǎn)單JavaScript對(duì)象;將對(duì)象鏈接(即設(shè)置對(duì)象的構(gòu)造函數(shù))到另一個(gè)對(duì)象;將步驟1中新創(chuàng)建的對(duì)象作為這個(gè)的上下文;如果函數(shù)不返回對(duì)象,則返回。如果您熟悉原型鏈:
優(yōu)雅地處理承諾回調(diào)(異步,等待)。
Async/await是一種基于Promise編寫異步或非阻塞代碼的新方法,通常被認(rèn)為是JS異步操作的最終和最優(yōu)雅的解決方案。相比承諾和回?fù)埽勺x性更強(qiáng),更簡(jiǎn)潔。畢竟then()總是讓人討厭。
Async是異步的意思,await是async wait的縮寫,即異步等待。
因此,語義上很好理解,async用于聲明函數(shù)是異步的,而await用于等待異步方法的執(zhí)行。
如果將async添加到一個(gè)函數(shù)中,該函數(shù)將返回一個(gè)承諾。
async?function?test()?{??return?"lly"}console.log(test())?//?->?Promise?{:?"lly"}您可以看到輸出是一個(gè)Promise對(duì)象。因此,ASYC函數(shù)返回一個(gè)Promise對(duì)象。如果在ASYC函數(shù)中直接返回一個(gè)直接量,ASYC會(huì)通過PromIse.resolve()將直接量封裝到一個(gè)Promise對(duì)象中并返回。
做個(gè)對(duì)比。
function?takeLongTime(n)?{????return?new?Promise(resolve?=>?{????????setTimeout(()?=>?resolve(n?+?200),?n);????});}function?step1(n)?{????console.log(`step1?with?${n}`);????return?takeLongTime(n);}function?step2(n)?{????console.log(`step2?with?${n}`);????return?takeLongTime(n);}function?step3(n)?{????console.log(`step3?with?${n}`);????return?takeLongTime(n);}Proime處理:
function?doIt()?{????console.time("doIt");????const?time1?=?300;????step1(time1)????????.then(time2?=>?step2(time2))????????.then(time3?=>?step3(time3))????????.then(result?=>?{????????????console.log(`result?is?${result}`);????????});}doIt();異步/等待處理
async?function?doIt()?{????console.time("doIt");????const?time1?=?300;????const?time2?=?await?step1(time1);????const?time3?=?await?step2(time2);????const?result?=?await?step3(time3);????console.log(`result?is?${result}`);}doIt();async/await的優(yōu)勢(shì)在于可以處理then的調(diào)用鏈,更清晰準(zhǔn)確地編寫代碼,優(yōu)雅地解決回調(diào)地獄的問題。
JS繼承
原型鏈,應(yīng)用或調(diào)用
某視頻剪輯軟件
MVVM框架
最好結(jié)合項(xiàng)目介紹舉例說明。在我的項(xiàng)目中,我通過vue.js代碼(axios或ajax通信)從后端接口(模型)請(qǐng)求用戶的個(gè)人信息,并在成功獲取響應(yīng)數(shù)據(jù)后。將VM數(shù)據(jù)給視圖(頁(yè)面),頁(yè)面會(huì)相應(yīng)地改變。因?yàn)閂UE是數(shù)據(jù)驅(qū)動(dòng)的,Vue本身將DOM綁定到數(shù)據(jù)。綁定一旦創(chuàng)建,數(shù)據(jù)發(fā)生變化,DOM發(fā)生變化,那么核心就是VM(ViewModel)。
狀態(tài)管理
突變是唯一能改變狀態(tài)的。Vue組件中的dispath啟動(dòng)動(dòng)作,然后動(dòng)作調(diào)用Commit重新分發(fā)突變,并提交突變以更改數(shù)據(jù)和視圖。很容易和自己的項(xiàng)目結(jié)合起來。
生命周期
Vue計(jì)算原理,計(jì)算和手表的區(qū)別;
Vue組件通信
vue路由器
當(dāng)一個(gè)動(dòng)態(tài)組件(route)被包裝時(shí),非活動(dòng)組件實(shí)例被緩存,主要用于保持組件狀態(tài),避免重新渲染。