日常學(xué)習(xí)知識(shí)點(diǎn)總結(jié)(JS篇)
1、閉包:
閉包就是函數(shù)中的函數(shù)沮翔,里面的函數(shù)可以訪問外面函數(shù)的變量秕磷,外面的變量是內(nèi)部函數(shù)的一部分。
閉包的作用:使用閉包可以訪問函數(shù)中的變量顷霹。
可以使變量長期保存在內(nèi)存中干毅,生命周期比較長。
缺點(diǎn):閉包不能濫用泼返,否則會(huì)導(dǎo)致內(nèi)存泄漏硝逢,影響網(wǎng)頁的性能。閉包使用完了绅喉,要立即釋放資源渠鸽,將引用變量指向null.
應(yīng)用場景:函數(shù)作為參數(shù)傳遞
函數(shù)作為返回值
為什么使用閉包 : 全局變量和局部變量都具有不可兼得的優(yōu)缺點(diǎn)。
全局變量:? 優(yōu): 可重用柴罐。? ? ? 缺: 易被污染徽缚。
局部變量:? 優(yōu): 僅函數(shù)內(nèi)可用,不會(huì)被污染革屠。? 缺: 不可重用!
何時(shí)使用: 即要重用一個(gè)變量凿试,又保護(hù)變量不被污染時(shí)排宰。
示例:? 1)var name = "The window";
var object =? {
? ? name: "my object",
? ? getNameFunc: function(){
? ? ? ? var self = this;
? ? ? return function (){
? ? ? ? ? ? return self.name;
? ? ? ? }
? }
}
console.log(object.getNameFunc()()); //my object
? ? ? ? ? ? 2)var name = "The window";
var object =? {
? ? name: "my object",
? ? getNameFunc: function(){
? ? ? return function (){
? ? ? ? ? ? return this.name;
? ? ? ? }
? }
}
console.log(object.getNameFunc()()); //The window
2、localStorage 那婉、sessionStorage 和 cookie 之間的區(qū)別:
共同點(diǎn):都是保存在瀏覽器端板甘,且都遵循同源策略(相同的協(xié)議、相同的主機(jī)名详炬、相同的端口)盐类。
不同點(diǎn):
localStorage的聲明周期是永久的,關(guān)閉頁面或?yàn)g覽器之后local Storage中的數(shù)據(jù)也不會(huì)消失呛谜。localStorage除非主動(dòng)刪除數(shù)據(jù)在跳,否則數(shù)據(jù)永遠(yuǎn)不會(huì)消失。
sessionStorage的生命周期是僅在當(dāng)前會(huì)話下有效隐岛。sessionStorage引入了一個(gè)“瀏覽器窗口”的概念猫妙,sessionStorage是在同源的窗口中始終存在的數(shù)據(jù)。只要這個(gè)瀏覽器窗口沒有關(guān)閉聚凹,即使刷新頁面或者進(jìn)入同源另一個(gè)頁面割坠,數(shù)據(jù)依然存在。但是sessionStorage在關(guān)閉了瀏覽器窗口后就會(huì)被銷毀元践。同時(shí)獨(dú)立的打開同一個(gè)窗口同一個(gè)頁面,sessionStorage也是不一樣的童谒。
cookie生命期為只在設(shè)置的cookie過期時(shí)間之前一直有效单旁,即便窗口或?yàn)g覽器關(guān)閉。存放數(shù)據(jù)大小為4K左右饥伊,有個(gè)數(shù)限制(各瀏覽器不同)象浑,一般不能超過20個(gè)。缺點(diǎn)是不能存儲(chǔ)大數(shù)據(jù)且不易讀取琅豆。
用法:
1)判斷瀏覽器是否支持localStorage/sessionStorage----if (window.localStorage) {? }
2)localStorage/sessionStorage都具有相同的操作方法
存儲(chǔ)數(shù)據(jù):setItem(key, value)---將value存儲(chǔ)到key字段
取出數(shù)據(jù):getItem(key)----獲取指定key本地存儲(chǔ)的值
修改數(shù)據(jù):setItem(key愉豺,newVal)----修改指定key本地存儲(chǔ)的值
刪除數(shù)據(jù):removeItem(key)----刪除指定key本地存儲(chǔ)的值
清除數(shù)據(jù):clear()----清楚所有本地存儲(chǔ)的數(shù)據(jù)
3)cookie
存儲(chǔ)數(shù)據(jù):window.document.cookie = 'XXXX';
取出數(shù)據(jù):document.cookie;
? ? cookie的作用:
解決了認(rèn)證(登錄)后,下次訪問還需要認(rèn)證(登錄)的重復(fù)認(rèn)證問題茫因。
可以記住用戶名和密碼蚪拦,增強(qiáng)用戶體驗(yàn)。
? ? cookie的缺點(diǎn):
安全性問題冻押,cookie數(shù)據(jù)保存在客戶端驰贷,有可能被篡改或盜取
Web Storage包含如下兩種機(jī)制:
sessionStorage為每一個(gè)給定的源(given origin)維持一個(gè)獨(dú)立的存儲(chǔ)區(qū)域,該存儲(chǔ)區(qū)域在頁面會(huì)話期間可用(即只要瀏覽器處于打開狀態(tài)洛巢,包括頁面重新加載和回復(fù))括袒。
localStorage同樣的功能,但在瀏覽器關(guān)閉稿茉,然后重新打開后數(shù)據(jù)仍然存在锹锰。
3芥炭、原型與原型鏈:
1)原型:在JS中原型是一個(gè)prototype對象,用于表示類型之間的關(guān)系
原型鏈:是針對構(gòu)造函數(shù)的恃慧。指對象之間的繼承關(guān)系园蝠,在JavaScript中是通過prototype對象指向父類對象,直到指向Object對象為止糕伐,這樣就形成了一個(gè)原型指向的鏈條砰琢,專業(yè)術(shù)語稱之為原型鏈。
當(dāng)試圖得到一個(gè)對象的某個(gè)屬性時(shí)良瞧,如果這個(gè)對象本身沒有這個(gè)屬性陪汽,那么會(huì)去它的_proto_(即構(gòu)造函數(shù)prototype)中尋找。如果一直找到最上層都沒找到褥蚯,就返回undefined挚冤。最上層是指------ object.prototype.__proto__===null.
2)構(gòu)造函數(shù)/原型對象/實(shí)例對象三者之間的關(guān)系以及原型鏈的訪問原理:
構(gòu)造函數(shù):是一種特殊的方法,它不同于普通的函數(shù)赞庶,普通的函數(shù)通過‘函數(shù)名()’即可進(jìn)行調(diào)用训挡,而構(gòu)造函數(shù)需要使用‘new 函數(shù)名()’進(jìn)行調(diào)用。主要用來創(chuàng)建對象時(shí)初始化對象歧强。
原型對象:是構(gòu)造函數(shù)所擁有的澜薄,在JavaScript規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè)prototype(原型)屬性摊册,指向另一個(gè)對象肤京。這個(gè)對象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)所擁有茅特。
實(shí)例對象:則是通過調(diào)用構(gòu)造函數(shù)而產(chǎn)生忘分。(例如:var? er = new? Person( ) )
總結(jié): 1)任何函數(shù)都具有一個(gè)prototype屬性,該屬性是一個(gè)對象白修。
2)構(gòu)造函數(shù)的prototype對象默認(rèn)都有一個(gè)constructor屬性妒峦,指向prototype對象所在的函數(shù)。
3)通過構(gòu)造函數(shù)得到的實(shí)例對象內(nèi)部會(huì)包含一個(gè)指向構(gòu)造函數(shù)的prototype對象的指針__proto__兵睛。
4)所有的實(shí)例都直接或間接繼承了原型對象的成員肯骇。
4、JS事件流
1)事件流:分為捕獲階段祖很,處于目標(biāo)階段累盗,冒泡階段三個(gè)階段
事件冒泡,從觸發(fā)的對象開始突琳,事件不斷往上傳遞
事件捕獲若债,從dom樹一直向下傳遞事件直到捕獲為止
2)事件綁定類型
dom0:通過element對象調(diào)用對應(yīng)的事件屬于綁定特定的事件,事件會(huì)在事件冒泡階段被捕獲拆融。
let btn = document.getElementById("myBtn");
btn.onclick = function(){// 由于onclick是attr蠢琳,所以可以通過.來獲取
? ? console.log(this.id);? ? //"myBtn"
};
dom2:通過addEventListener來綁定事件啊终,removeEventListener來移除事件。element.addEventListener(event,function,useCapture)中的第三個(gè)參數(shù)可以控制指定事件是否在捕獲或冒泡階段執(zhí)行傲须。true---事件句柄在捕獲階段執(zhí)行蓝牲。false(默認(rèn))---事件句柄在冒泡階段執(zhí)行。IE9泰讽、Firefox例衍、Safari、Chrome 和 Opera 支持 DOM2 級事件處理程序已卸。
let btn = document.getElementById("myBtn");
btn.addEventListener('click', function(event){
console.log(this.id);? ? //"myBtn"
},false);
btn.addEventListener("click", function(){// 添加多個(gè)回調(diào),觸發(fā)的時(shí)候依次調(diào)用
? ? alert("Hello world!");
}, false);
對于ie8之前的可以使用attachEvent添加事件佛玄,detachEvent解除事件
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){// 事件類型必須是onclick,跟dom2不一樣
? ? alert("Clicked");
});
三者的區(qū)別:
1)dom2累澡,attachEvent可以為一個(gè)事件添加多個(gè)相應(yīng)函數(shù)梦抢,彼此之間不會(huì)覆蓋。dom0則不可以愧哟。
2)dom0的兼容性好奥吩,支持所有的瀏覽器。dom2不支持ie瀏覽器蕊梧,所以對于ie瀏覽器事件處理使用attachEvent霞赫。由于IE只支持冒泡事件,所以attachEvent肥矢,沒有第三個(gè)參數(shù)端衰。
3)dom0在注銷事件的時(shí)候,只要將對應(yīng)的事件屬性置為null即可橄抹。dom2調(diào)用removeEventListener函數(shù)的時(shí)候靴迫,參數(shù)要與addEventListener一樣惕味,也就是說楼誓,在addEventListener指定的函數(shù)的回調(diào)不能是一個(gè)匿名函數(shù),不然在注銷不到名挥。因?yàn)閮蓚€(gè)函數(shù)對象是不一樣的疟羹,雖然內(nèi)容一樣。
3)事件對象:
如果將回調(diào)函數(shù)直接綁定到目標(biāo)對象上禀倔,那么this榄融,target,currentTarget都是一樣的救湖,都是目標(biāo)對象愧杯。
如果是綁定到父級元素上,那么this和currentTarget都等于父級元素鞋既,也即是回調(diào)函數(shù)被綁定的對象力九,target才是真正觸發(fā)的對象耍铜。
4)document 加載事件回調(diào)
DOMContentLoading:在dom樹加載完成之后被觸發(fā),不等待css跌前,js棕兼,img等下載
onload:等待頁面的內(nèi)容都加載完畢之后被觸發(fā)
5)事件集合:
鼠標(biāo)事件:click(單機(jī))、dbclick(雙擊)抵乓、mousedown(鼠標(biāo)按下)伴挚、mouseout(鼠標(biāo)移走)、mouseover(鼠標(biāo)彈起)灾炭、mouseup(鼠標(biāo)移動(dòng))茎芋、mousemover(鼠標(biāo)移動(dòng))
鍵盤事件:keydown(鍵按下)、keydown(按鍵)咆贬、keyup(鍵起來)
HTML事件:load(加載頁面)败徊、unload(卸載離開頁面)、change(改變內(nèi)容)掏缎、scroll(滾動(dòng))皱蹦、focus(獲得焦點(diǎn))、blur(失去焦點(diǎn))
阻止事件冒泡的方法:
1)event.stopPropagation( )眷蜈;? 2)return false;? ? 3)event.preventDefault( )
5沪哺、繼承:
方法1:原型鏈+借用構(gòu)造函數(shù)組合
// 父類
function Person(){
? this.name = name;
? ? this.sum = function (){
? ? ? ? console.log(this.name);
? ? }
}
Person.prototype.age = 10;
function SubType(name){
? ? Person.call(this,name); // 借用構(gòu)造函數(shù)模式
}
SubType.prototype = new Person(); // 原型鏈繼承
var sub = new SubType("gar");
console.log(sub.name); // gar,繼承了構(gòu)造函數(shù)屬性
console.log(sub.age); // 10酌儒,繼承了父類原型的屬性
優(yōu)點(diǎn):構(gòu)造函數(shù)可以傳參辜妓,不會(huì)與父類引用屬性共享,可以復(fù)用父類的函數(shù)
缺點(diǎn):繼承了父類函數(shù)時(shí)忌怎,調(diào)用了父類構(gòu)造函數(shù)籍滴,導(dǎo)致子類的原型上多了不需要的父類屬性,存在內(nèi)存上的浪費(fèi)榴啸。
方法2:ES6中class的繼承孽惰,class實(shí)現(xiàn)繼承的核心在于使用extends表明繼承自哪個(gè)父類,并且在子類構(gòu)造函數(shù)中必須調(diào)用super鸥印。此段代碼可以看成Parent.call(this,value);
6勋功、http協(xié)議:
HTTP,即超文本傳輸協(xié)議库说,這個(gè)協(xié)議規(guī)定了瀏覽器和萬維網(wǎng)服務(wù)器之間互相通信的規(guī)則狂鞋。客戶端發(fā)送給服務(wù)器的格式叫“請求協(xié)議”潜的;服務(wù)器發(fā)送給客戶端的格式叫“響應(yīng)協(xié)議”骚揍。
特點(diǎn):http叫超文本傳輸協(xié)議,基于請求/響應(yīng)模式的啰挪;http是無狀態(tài)協(xié)議(服務(wù)器不需要知道客戶端是誰,只認(rèn)請求信不,一次請求request,一次響應(yīng)response)纤掸,ftp(端口號(hào)為21)是有狀態(tài)。
URL:統(tǒng)一資源定位符浑塞,就是一個(gè)網(wǎng)址:協(xié)議名://域名:端口/路徑借跪。
http默認(rèn)的請求方法是GET:
沒有請求體,數(shù)據(jù)必須在1K之內(nèi)酌壕,GET請求的數(shù)據(jù)會(huì)暴露在瀏覽器的地址欄中
get和post的區(qū)別:
主要有以下幾個(gè)方面:
1)url可見性:get掏愁,參數(shù)url可見;post卵牍,url參數(shù)不可見
2)數(shù)據(jù)傳輸上:get果港,通過拼接url進(jìn)行傳遞參數(shù);post糊昙,通過body體傳輸參數(shù)
3)緩存性:get請求是可以緩存的辛掠;post請求不可以緩存
4)后退頁面的反應(yīng):get請求頁面后退時(shí),不產(chǎn)生影響释牺;post請求頁面后退時(shí)萝衩,會(huì)重新提交請求
5)傳輸數(shù)據(jù)的大小:get一般傳輸數(shù)據(jù)大小不超過2k-4k(根據(jù)瀏覽器不同没咙,限制不一樣猩谊,但相差不大);post請求傳輸數(shù)據(jù)的大小根據(jù)php.init配置文件設(shè)定祭刚,也可以無限大牌捷。
6)安全性:post肯定要比get安全,畢竟傳輸參數(shù)時(shí)url不可見涡驮,但也擋不住部分人閑的沒事在那抓包玩暗甥。對傳遞的參數(shù)進(jìn)行加密,其實(shí)都一樣捉捅。
狀態(tài)碼:200:請求成功撤防,瀏覽器會(huì)把響應(yīng)體內(nèi)容(通常時(shí)html)顯示在瀏覽器中
404:請求的資源沒有找到,說明客戶端錯(cuò)誤的請求了不存在的資源
500:請求的資源找到了锯梁,但服務(wù)器內(nèi)部出現(xiàn)了錯(cuò)誤
302:重定向即碗,當(dāng)響應(yīng)碼為302時(shí)焰情,表示服務(wù)器要求瀏覽器重新再發(fā)一個(gè)請求陌凳,服務(wù)器會(huì)發(fā)送一個(gè)響應(yīng)頭Location,它指定了新請求的URL地址内舟。
304:服務(wù)端內(nèi)容未改變合敦,將使用緩存在瀏覽器端的數(shù)據(jù)。
http請求報(bào)文:一個(gè)http請求報(bào)文由請求行(request line)/請求頭部(header)/空行/請求數(shù)據(jù)四部分組成验游。
1)請求行充岛,由請求方法字段/URL字段/http協(xié)議版本字段3部分組成保檐,它們用空格分隔。
2)請求頭崔梗,由關(guān)鍵字/值對組成夜只,每行一對,關(guān)鍵字和值用英文冒號(hào)“:”分割蒜魄。請求頭部通知服務(wù)器有關(guān)客戶端請求的信息扔亥,典型的請求頭有:User-Agent,產(chǎn)生請求的瀏覽器類型谈为;Accept旅挤,客戶端可識(shí)別的內(nèi)容類型列表;Host伞鲫,請求的主機(jī)名粘茄,允許多個(gè)域名同處一個(gè)IP地址,即虛擬主機(jī)秕脓。
3)空行柒瓣,最后一個(gè)請求頭之后是一個(gè)空行,發(fā)送回車符和換行符吠架,通知服務(wù)器以下不再有請求頭嘹朗。
4)請求數(shù)據(jù),請求數(shù)據(jù)不在GET方法中使用诵肛,而是在POST方法中使用屹培。與請求數(shù)據(jù)相關(guān)的最常使用的請求頭是Content-Type和Content-Length。
http報(bào)文:
http響應(yīng)也由三部分組成怔檩,分別是:狀態(tài)行/消息報(bào)頭/響應(yīng)正文
http協(xié)議1.0/1.1/2.0的區(qū)別:
? ? 1)http1.0褪秀,短鏈接,每一個(gè)請求建立一個(gè)TCP連接薛训,請求完成后立馬斷開連接媒吗。導(dǎo)致連接無法復(fù)用,帶寬無法被充分利用乙埃,以及后續(xù)健康請求被阻塞闸英。
2)http1.1,長連接介袜,多個(gè)http請求可以復(fù)用一個(gè)TCP連接甫何,服務(wù)器按照隊(duì)列的先進(jìn)先出(FIFO)原則來處理不同的Request;增加connection header,該header用來說明客戶端與服務(wù)器端TCP的連接方式遇伞,若connection為close則使用短鏈接辙喂,若connection為keep-alive則使用長連接。
3)http2.0,多路復(fù)用巍耗,允許同時(shí)通過單一的HTTP/2連接發(fā)起多重的請求-響應(yīng)消息秋麸,可以很容易的去實(shí)現(xiàn)多流并行而不用依賴建立多個(gè)TCP連接跌榔,把http協(xié)議通信的基本單位縮小為一個(gè)一個(gè)幀蒸痹,這些幀對應(yīng)著邏輯流中的消息逞盆,并行的在同一個(gè)TCP連接上雙向交換消息览芳。二進(jìn)制分幀面褐,http2在應(yīng)用層(http/2)和傳輸層(TCP/UDP)之間增加一個(gè)二進(jìn)制分幀層头镊,在不改動(dòng)http1.X的情況下疆液,解決了http1.1的性能限制雳窟,改進(jìn)傳輸性能孽水,實(shí)現(xiàn)低延遲和高吞吐量票腰。http/2通信都在一個(gè)連接上完成,這個(gè)連接可以承載任意數(shù)量的雙向數(shù)據(jù)流女气。
7杏慰、http與https的區(qū)別:
http,超文本傳輸協(xié)議炼鞠;
https缘滥,超文本傳輸安全協(xié)議。
https經(jīng)由http進(jìn)行通信谒主,但利用SSL/TLS來加密數(shù)據(jù)包朝扼。https開發(fā)的主要目的,是提供對網(wǎng)站服務(wù)器的身份認(rèn)證霎肯,保證交換數(shù)據(jù)的隱私與完整性擎颖。
主要區(qū)別:1)傳輸信息安全性不同:http明文傳輸,數(shù)據(jù)都是未加密的观游,安全性較差搂捧;https數(shù)據(jù)傳輸過程時(shí)加密的,安全性較好
2)申請方式:http協(xié)議免費(fèi)申請懂缕,https協(xié)議需要到CA(數(shù)字證書認(rèn)證機(jī)構(gòu))申請證書允跑,需要繳費(fèi)
3)響應(yīng)速度:http頁面響應(yīng)速度比https快,主要是因?yàn)閔ttp使用TCP三次握手建立連接搪柑,客戶端和服務(wù)器需要交換3個(gè)包聋丝,而https除了TCP的3個(gè)包,還要加上SSL握手的9個(gè)包工碾,一共12個(gè)包
4)端口不同:http和https使用的完全不同的連接方式弱睦,用的端口也不一樣,http是80端口倚喂,https是443端口
5)耗費(fèi)資源:https其實(shí)就是建構(gòu)在SSL/TLS之上的http協(xié)議每篷,所以https比http要更耗費(fèi)服務(wù)器資源。
8端圈、數(shù)組常用方法:
改變原數(shù)組的方法:
1)push( )把里面的內(nèi)容添加到數(shù)組末尾焦读,并返回修改后的長度
? ? pop( )移除數(shù)組最后一項(xiàng),返回移除的那個(gè)值舱权,減少數(shù)組的length
2)shift( )刪除原數(shù)組第一項(xiàng)矗晃,并返回刪除元素的值;如果數(shù)組為空則返回undefined
? ? unshift( )將參數(shù)添加到原數(shù)組開頭宴倍,并返回?cái)?shù)組的長度
3)sort( )將數(shù)組里的項(xiàng)從小到大排序
4)reverse( )反轉(zhuǎn)數(shù)組項(xiàng)的順序
5)splice( )刪除张症、插入和替換。
6)slice( )返回從原數(shù)組中指定開始下標(biāo)到結(jié)束下標(biāo)之間的項(xiàng)組成的新數(shù)組鸵贬。
7)reduce( )對數(shù)組中的每個(gè)元素執(zhí)行一個(gè)由您提供的reducer函數(shù)(升序執(zhí)行)俗他,將其結(jié)果匯總為單個(gè)返回值。reducer函數(shù)接收4個(gè)參數(shù):Accumulator(acc)累計(jì)器阔逼,Current Value(cur)當(dāng)前值兆衅,Current Index(idx)當(dāng)前索引,Source Array(src)源數(shù)組
沒有改變原數(shù)組的方法:
8)join,就是把數(shù)組轉(zhuǎn)換成字符串嗜浮,然后給規(guī)定個(gè)連接字符羡亩,默認(rèn)是逗號(hào)(,)
9)concat( )將參數(shù)添加到原數(shù)組中
10)indexOf( )要查找的項(xiàng)位置的索引。 從數(shù)組的開頭(位置 0)開始向后查找危融。
? ? lastIndexOf( )要查找的項(xiàng)位置的索引畏铆。從數(shù)組的末尾開始向前查找。
11)forEach( )對數(shù)組進(jìn)行遍歷循環(huán)吉殃,對數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)辞居。這個(gè)方法沒有返回值。
12)map( )指“映射”蛋勺,對數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)速侈,返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。
13)filter( )“過濾”功能迫卢,數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)倚搬,返回滿足過濾條件組成的數(shù)組。
14)every( )判斷數(shù)組中每一項(xiàng)都是否滿足條件乾蛤,只有所有項(xiàng)都滿足條件每界,才會(huì)返回true。
14)some( )判斷數(shù)組中是否存在滿足條件的項(xiàng)家卖,只要有一項(xiàng)滿足條件眨层,就會(huì)返回true。
map和forEach相同點(diǎn):
1)都是循環(huán)遍歷數(shù)組中的每一項(xiàng)
2)forEach和map方法里每次執(zhí)行匿名函數(shù)都支持3個(gè)參數(shù)上荡,參數(shù)分別是item(當(dāng)前每一項(xiàng))趴樱,index(索引值)馒闷,arr(原數(shù)組)
3)匿名函數(shù)中的this都是指向window
4)只能遍歷數(shù)組
5)都不會(huì)改變原數(shù)組
map和forEach區(qū)別:
map方法返回一個(gè)新的數(shù)組,數(shù)組中的元素為原始數(shù)組調(diào)用函數(shù)處理后的值叁征。若arr為空數(shù)組纳账,則map方法返回的也是一個(gè)空數(shù)組,forEach對于空數(shù)組是不會(huì)調(diào)用回調(diào)函數(shù)的
無論arr是不是空數(shù)組捺疼,forEach返回的都是undefined疏虫。這個(gè)方法只是將數(shù)組中的每一項(xiàng)作為callback的參數(shù)執(zhí)行一次。
9啤呼、字符串常用方法:
1)charAt():返回在指定位置的字符
2)charCodeAt():返回咋指定位置的字符的Unicode編碼
3)concat():連接字符串
4)indexOf(): 檢索字符串卧秘,返回的是字符在字符串的下標(biāo)
5)match():在字符串內(nèi)檢索指定的值或找到一個(gè)或多個(gè)正則表達(dá)式的匹配,返回的是值而不是值的位置官扣。
6)replace():替換匹配的字符串
7)search():檢索與字符串匹配的子串翅敌,返回的是地址
8)slice():提取字符串片段,并在新的字符串中返回被提取的部分
9)split():把字符分割成數(shù)組
10)toLocaleLowerCase():把字符串轉(zhuǎn)換成小寫
? ? ? ? ? ? toLocaleUpperCase():把字符串準(zhǔn)換成大寫
11)ubstr():從起始索引號(hào)提取字符串中指定書目的字符,空格不占位
12)subString():提取字符串中兩個(gè)指定索引號(hào)之間的字符惕蹄,空格占位
10哼御、對象常用方法:
1)創(chuàng)建:
Object.create():參數(shù)是一個(gè)對象,并且該對象作為新創(chuàng)建對象的原型焊唬。
2)屬性賦值:
obj.name='lalala';當(dāng)對象存在但是屬性不存在的時(shí)候恋昼,給對象添加一個(gè)屬性。
3)刪除屬性:
delete obj['name']; 在刪除數(shù)組中元素的時(shí)候赶促,刪除了屬性液肌,但數(shù)組中的站位還在,長度不變鸥滨。
4)檢測屬性
in:檢測對象的自有屬性和繼承屬性中是否有該屬性嗦哆。有則返回true, 否則返回false婿滓。
hasOwnProperty():測試當(dāng)前屬性是不是對象的自有屬性老速。
5)枚舉屬性
for/in 其可以遍歷對象中的所有的可枚舉屬性,包括當(dāng)前對象的自有屬性和繼承屬性凸主。
Object.keys() 遍歷對象的自有屬性橘券,返回的是一個(gè)數(shù)組,其中存在的是對象中的可枚舉屬性名稱組成卿吐。
Object.getOwnPropertyNames() 其返回的是數(shù)組旁舰,但是是所有的自有屬性名稱的數(shù)組。
Object.entries()? ? 返回一個(gè)包含[key, value]給定對象自己的可枚舉字符串屬性的所有對的數(shù)組嗡官。
6)Object.assign(target, ...resouce); 將所有可枚舉屬性的值從一個(gè)或多個(gè)源對象復(fù)制到目標(biāo)對象箭窜。它將返回目標(biāo)對象。target: 目標(biāo)對象? resouce: 源對象?
11衍腥、網(wǎng)頁從輸入網(wǎng)址到渲染完成經(jīng)歷了哪些過程磺樱?
? ? 大致分如下步驟:a).輸入網(wǎng)址
b).發(fā)送到DNS(域名解析)服務(wù)器纳猫,并獲取域名對應(yīng)的web服務(wù)器對應(yīng)的IP地址;
c).與web服務(wù)器建立TCP連接竹捉;
d).瀏覽器向web服務(wù)器發(fā)送http請求
e).web服務(wù)器響應(yīng)請求芜辕,并返回指定的url的數(shù)據(jù)(或錯(cuò)誤信息,或重定向的新的url地址)
f).瀏覽器下載web服務(wù)器返回的數(shù)據(jù)及解析html源文件
g).生成DOM樹活孩,解析CSS物遇,JS乖仇,瀏覽器渲染
HTML parser--->DOM Tree(標(biāo)記化算法憾儒,進(jìn)行元素狀態(tài)的標(biāo)記;dom樹構(gòu)建)
CSS parser--->Style Tree(解析css代碼乃沙,生成樣式樹)
attachment--->Render Tree (結(jié)合dom樹與style樹起趾,生成渲染樹)
layout:布局
GPU painting:像素繪制頁面
12、常見的幾種跨域解決方案:
1)JSONP:動(dòng)態(tài)創(chuàng)建一個(gè)script標(biāo)簽警儒。利用script標(biāo)簽的src屬性不受同源策略限制训裆。因?yàn)樗械膕rc屬性和href屬性都不受同源策略限制∈癫可以請求第三方服務(wù)器數(shù)據(jù)內(nèi)容边琉。
原理:首先在客戶端注冊一個(gè)callback,然后把callback的名字傳給服務(wù)器记劝。此時(shí)变姨,服務(wù)器先生成json數(shù)據(jù),然后以JavaScript語法的方式厌丑,生成function定欧,function名字就是傳遞上來帶參數(shù)jsonp。最后將json數(shù)據(jù)直接以入?yún)⒌姆绞脚停胖胒unction中砍鸠,這樣就生成js語法的文檔,返回給客戶端耕驰∫瑁客戶端瀏覽器,解析script變遷朦肘,并執(zhí)行返回JavaScript文檔托嚣,此時(shí)數(shù)據(jù)作為參數(shù),傳入了客戶端預(yù)先定義好的callback函數(shù)里厚骗。簡單的說示启,就是利用script標(biāo)簽沒有跨域限制的“漏洞”來達(dá)到與第三方通訊的目的。
步驟:
a. 去創(chuàng)建一個(gè)script標(biāo)簽
b. script的src屬性設(shè)置接口地址
c. 接口參數(shù)领舰,必須要帶一個(gè)自定義函數(shù)名夫嗓,要不然后臺(tái)無法返回?cái)?shù)據(jù)
d. 通過定義函數(shù)名去接收后臺(tái)返回?cái)?shù)據(jù)
//去創(chuàng)建一個(gè)script標(biāo)簽
var script = document.createElement('script');
//script的src屬性接口地址迟螺,并帶一個(gè)callback回調(diào)函數(shù)名稱
script.src = 'http://127.0.0.1:8888/index.php?callback=jsonpCallback';
//插入到頁面
document.head.appendChild(script);
//通過定義函數(shù)名去接收后臺(tái)返回?cái)?shù)據(jù)
function jsonpCallback(data){
? ? //注意,jsonp返回的數(shù)據(jù)是json對象可以直接使用
? ? //ajax? 取得數(shù)據(jù)是json字符串需要轉(zhuǎn)換成json對象才可以使用
}
總結(jié)一下舍咖,json是一種數(shù)據(jù)格式矩父,jsonp是一種數(shù)據(jù)調(diào)用的方式,帶callback的json就是jsonp.
2)基于iframe的跨域解決方案
window.name
document.domin
location.hash
post.message
3)CORS:跨域資源共享排霉。
服務(wù)器設(shè)置Access-Control-Allow-OriginHTTP響應(yīng)頭之后窍株,瀏覽器將會(huì)允許跨域請求。瀏覽器需要支持HTML5攻柠,可以支持POST球订,PUT等方法兼容ie9以上。
需要后臺(tái)設(shè)置:Access-Control-Allow-Origin: *? ? ? //允許所有域名訪問
Access-Control-Allow-Origin: http://a.com? ? ? //只允許所有域名訪問
4)設(shè)置document.domain
相同主域名不同子域名下的頁面瑰钮,可以設(shè)置document.domain讓它們同域冒滩。
同域document提供的是頁面間的互操作,需要載入iframe頁面浪谴。
// URL http://a.com/foo
var ifr = document.createElement('iframe');
ifr.src = 'http://b.a.com/bar';
ifr.onload = function(){
? ? var ifrdoc = ifr.contentDocument || ifr.contentWindow.document;
? ? ifrdoc.getElementsById("foo").innerHTML);
};
ifr.style.display = 'none';
document.body.appendChild(ifr);
5)用Apache做轉(zhuǎn)發(fā)(逆向代理)开睡,讓跨域變成同域
13、目前主流瀏覽器的內(nèi)核分別是:
IE----Trident
Chrome---Blink
Firefox----Gecko
Safari----webkit
Mozilla-----Servo苟耻, 在 Firefox Quantum (火狐“量子”版本) 瀏覽器的57版本上使用了Servo CSS Style引擎
14篇恒、JS/jQuery/Vue分別是怎樣獲取標(biāo)簽的
javaScript:document.getElementById(“div”);//獲取id
document.getElementsByClassName(“div”);//獲取class類名
document.getElementsByTagName(“p”);//獲取標(biāo)簽
document.getElementsByName(“box”);//獲取input里name值
jQuery:$('#id');//獲取id
$('.class');//獲取class類名
$('input')凶杖;//獲取標(biāo)簽
Vue: 使用ref胁艰,給相應(yīng)的元素加ref="name",然后再this.$refs.name獲取到該元素
注意:在獲取相應(yīng)元素之前官卡,必須在mount鉤子進(jìn)行掛在蝗茁,否則獲取到的值為空。
15寻咒、JS的數(shù)據(jù)類型分類:
基本數(shù)據(jù)類型:Undefined哮翘,Null,Boolean毛秘,String饭寺,Number,Symbol
引用數(shù)據(jù)類型:對象叫挟,數(shù)組艰匙,函數(shù)
棧,存儲(chǔ)基本類型值和指定代碼得環(huán)境
堆抹恳,存儲(chǔ)引用類型值得空間
objA instanceof objB:objA的原型鏈上是否能找到objB的原型
instanceof 和 typeof區(qū)別:
typeof返回該參數(shù)數(shù)據(jù)類型员凝,返回值為字符串
instanceof判斷參數(shù)是否存在繼承關(guān)系,返回值為布爾值
判斷數(shù)據(jù)類型:
1)typeof---返回對應(yīng)的數(shù)據(jù)類型奋献,區(qū)分基本數(shù)據(jù)類型健霹,如果是引用類型(如果是對象和數(shù)組)旺上,那么返回的都是Object,無法區(qū)分糖埋。
2)instanceof---只適用于對象類型宣吱,判斷一個(gè)對象是否屬于某個(gè)構(gòu)造函數(shù)的實(shí)例。不適用于簡單類型的數(shù)據(jù)類型瞳别,返回boolean值
語法:變量名? instanceof? 數(shù)據(jù)類型? ||? ? 實(shí)例對象名? instanceof? 構(gòu)造函數(shù)
3)constructor---默認(rèn)指向prototype屬性所在的構(gòu)造函數(shù)征候,用來判斷數(shù)據(jù)類型(包括數(shù)組、日期祟敛、對象)疤坝,返回boolean值
語法:變量名.constructor === 數(shù)據(jù)類型
4)jQuery.type( )---判斷數(shù)據(jù)類型(包括日期、正則垒棋、undefined卒煞、null等)痪宰。其判斷的結(jié)果顯示都是小寫的字符串形式
語法:jQuery.type(變量名)
5)Object.prototype.toString---toString是Object原型上的一個(gè)方法叼架,該方法默認(rèn)返回的是toString運(yùn)行時(shí)this指向的對象類型,返回的格式為[object衣撬,xxx]乖订,xxx是具體的數(shù)據(jù)類型。注具练,所有對象的原型鏈最終都指向了Object乍构。
16、作用域與作用域鏈
ES6 之前 JavaScript 沒有塊級作用域,只有全局作用域和函數(shù)作用域
作用域:就是一個(gè)獨(dú)立的地盤扛点,讓變量不會(huì)外泄哥遮、暴露出去。作用域最大的用處就是隔離變量陵究,不同作用域下同名變量不會(huì)有沖突眠饮。
作用域鏈:是針對變量的,先在自己的變量范圍中查找铜邮,如果沒有找到仪召,就向父級作用域?qū)ふ遥绻讣壱矝]有松蒜,就再一層一層向上尋找扔茅,直到找到全局作用域還是沒找到,就宣布放棄秸苗。這種一層一層的關(guān)系召娜,就是作用域鏈 。
17惊楼、作用域與執(zhí)行上下文:
JavaScript 屬于解釋型語言玖瘸,JavaScript 的執(zhí)行分為:解釋和執(zhí)行兩個(gè)階段,這兩個(gè)階段所做的事并不一樣:
解釋階段:
詞法分析
語法分析
作用域規(guī)則確定
執(zhí)行階段:
創(chuàng)建執(zhí)行上下文
執(zhí)行函數(shù)代碼
垃圾回收
JavaScript 解釋階段便會(huì)確定作用域規(guī)則吐句,因此作用域在函數(shù)定義時(shí)就已經(jīng)確定了,而不是在函數(shù)調(diào)用時(shí)確定店读,但是執(zhí)行上下文是函數(shù)執(zhí)行之前創(chuàng)建的嗦枢。執(zhí)行上下文最明顯的就是 this 的指向是執(zhí)行時(shí)確定的。而作用域訪問的變量是編寫代碼的結(jié)構(gòu)確定的屯断。
作用域和執(zhí)行上下文之間最大的區(qū)別是:
執(zhí)行上下文在運(yùn)行時(shí)確定文虏,隨時(shí)可能改變;作用域在定義時(shí)就確定殖演,并且不會(huì)改變氧秘。
18、Js宏觀任務(wù)與微觀任務(wù):
宏觀任務(wù):宿主(瀏覽器/node)發(fā)起的任務(wù)為宏觀任務(wù)趴久,如:整體代碼script/ setTimeout/ setInterval/
微觀任務(wù):JavaScript引擎發(fā)起的任務(wù)為微觀任務(wù)丸相,如:promise/ process.nextTick
執(zhí)行順序:同步>異步;微任務(wù)>宏任務(wù)
19彼棍、前端緩存:
1)Http緩存:
http緩存可以根據(jù)是否需要重新向服務(wù)器發(fā)起請求來分類灭忠,分為強(qiáng)制緩存和協(xié)商緩存。
強(qiáng)制緩存座硕,主要是通過http請求頭中的Cache-Control和Expire兩個(gè)字段控制弛作。Expire是HTTP1.0標(biāo)準(zhǔn)下的字段。一般华匾,我們會(huì)設(shè)置Cache-Control的值為“public映琳,max-age=XXX”,表示在XXX秒內(nèi)再次訪問該資源蜘拉,均使用本地的緩存萨西,不再向服務(wù)器發(fā)起請求。
如果緩存期過了旭旭,就使用協(xié)商緩存解決問題谎脯。協(xié)商緩存需要請求,如果緩存有效會(huì)返回304您机。
協(xié)商緩存需要客戶端和服務(wù)端共同實(shí)現(xiàn)穿肄,和強(qiáng)緩存一樣,也有兩種實(shí)現(xiàn)方式:
Last-Modified 和 If-Modified-Since际看,Last-Modified表示本地文件最后修改日期咸产,If-Modified-Since會(huì)將Last-Modified的值發(fā)送給服務(wù)器,詢問服務(wù)器在該日期后資源是否由更新仲闽,有更新的話就會(huì)將新的資源發(fā)送回來脑溢。? 但是如果在本地打開緩存文件,就會(huì)造成Last-Modified被修改,所以在HTTP/1.1出現(xiàn)了ETag屑彻。
ETag和If-None-Match,ETag類似于文件指紋验庙,If-None-Match會(huì)將當(dāng)前ETag 發(fā)送給服務(wù)器,詢問該資源ETag是否變動(dòng)社牲,有變動(dòng)的話就將新的資源發(fā)送回來粪薛。并且ETag優(yōu)先級比Last-Modified高。
一個(gè)較為合理的緩存方案:HTML:使用協(xié)商緩存搏恤;CSS & JS & 圖片:使用強(qiáng)緩存违寿,文件命名帶上hash值。
2)瀏覽器緩存
Cookie主要用于用戶信息的存儲(chǔ)熟空,Cookie的內(nèi)容可以自動(dòng)在請求的時(shí)候被傳遞給服務(wù)器藤巢。
LocalStorage的數(shù)據(jù)將一直保存在瀏覽器內(nèi),直到用戶清除瀏覽器緩存數(shù)據(jù)為止息罗。
SessionStorage的其他屬性同LocalStorage,只不過它的生命周期同標(biāo)簽頁的生命周期掂咒,當(dāng)標(biāo)簽頁被關(guān)閉時(shí),SessionStorage也會(huì)被清楚迈喉。
WebSql和IndexDB主要用在前端有大容量存儲(chǔ)需求的頁面上绍刮,例如,在線編輯瀏覽器或者網(wǎng)頁郵箱弊添。
往返緩存录淡,又稱為BFCache捌木,是瀏覽器在前進(jìn)后退按鈕上為了提升歷史頁面的渲染速度的一種策略油坝。該策略具體表現(xiàn)為,當(dāng)用戶前往新頁面時(shí)刨裆,將當(dāng)前頁面的瀏覽器DOM狀態(tài)保存到BFCache中澈圈;當(dāng)用戶點(diǎn)擊后退按鈕的時(shí)候,將頁面直接從BFCache中加載帆啃,節(jié)省了網(wǎng)絡(luò)請求的時(shí)間瞬女。
20、淺拷貝與深拷貝:
淺拷貝:以賦值的形式拷貝引用對象努潘,仍指向同一個(gè)地址诽偷,修改時(shí)原對象也受到影響(尋址操作,例如:訪問數(shù)據(jù)類型為數(shù)組)
淺拷貝的實(shí)現(xiàn)方式:
Object.assign():只復(fù)制源對象中可枚舉的屬性和對象自身的屬性
Array.prototype.concat()
Array.prototype.slice()
深拷貝:完全拷貝一個(gè)新對象疯坤,修改時(shí)原對象不再受到任何影響(尋值操作报慕,例如:訪問數(shù)據(jù)類型為字符串)
深拷貝的實(shí)現(xiàn)方式:
jquery 提供一個(gè)$.extend可以用來做深拷貝
JSON.parse(JSON.stringify())
手寫遞歸方法,遞歸實(shí)現(xiàn)深拷貝的原理:要拷貝一個(gè)數(shù)據(jù)压怠,我們肯定要去遍歷它的屬性眠冈,如果這個(gè)對象的屬性仍是對象,繼續(xù)使用這個(gè)方法菌瘫,如此往復(fù)蜗顽。
21布卡、new關(guān)鍵字的理解:
在JavaScript中,new關(guān)鍵字用來創(chuàng)建一個(gè)類(模擬類)的實(shí)例對象雇盖。實(shí)例化對象之后忿等,也就繼承了類的屬性和方法。
使用new關(guān)鍵字后崔挖,意味做了幾件事情:
1)創(chuàng)建一個(gè)新的空對象{? }
2)設(shè)置這個(gè)對象原型指向構(gòu)造函數(shù)这弧,即obj._proto_ = Person.prototype
3)執(zhí)行構(gòu)造函數(shù),當(dāng)this關(guān)鍵字被提及的時(shí)候虚汛,使用新創(chuàng)建的對象的屬性
4)返回新創(chuàng)建的對象(如果構(gòu)造函數(shù)有自己return時(shí)匾浪,則返回該值)
22、this的全面解析
this的值是在執(zhí)行的時(shí)候才能確認(rèn)卷哩,定義的時(shí)候不能確認(rèn)蛋辈!-----因?yàn)閠his是執(zhí)行上下文環(huán)境的一部分,而執(zhí)行上下文需要在代碼執(zhí)行之前確定将谊,而不是定義的時(shí)候冷溶。
主要幾種情況:
1)普通函數(shù):this 指向調(diào)用其所在函數(shù)的對象,誰調(diào)的函數(shù)指向誰
2)構(gòu)造函數(shù):this指向被創(chuàng)建的新對象--實(shí)例對象
3)DOM事件:this指向觸發(fā)事件的dom元素
4)call,? apply和bind:this是第一個(gè)參數(shù)
xx.call(this,? arg1, arg2)
xx.apply(this, [arg1,arg2])
xx.bind(this)(arg1)
5)setTimeout 和 setInterval:this指向全局
6)箭頭函數(shù)this指向:箭頭函數(shù)定義的位置尊浓,就是this的指向逞频,一般情況會(huì)是window
23、JS的設(shè)計(jì)模型:
1)單例模式
定義:保證一個(gè)類僅有一個(gè)實(shí)例栋齿,并提供一個(gè)訪問它的全局訪問點(diǎn)苗胀。實(shí)現(xiàn)的方法為先判斷實(shí)例存在與否,如果存在則直接返回瓦堵,如果不存在就創(chuàng)建了再返回基协,這就確保了一個(gè)類只有一個(gè)實(shí)例對象。
使用場景菇用,一個(gè)單一對象澜驮。比如:彈窗,無論點(diǎn)擊多少次惋鸥,彈窗只應(yīng)該被創(chuàng)建一次杂穷。
2)策略模式
定義:定義一系列的算法,把他們一個(gè)個(gè)封裝起來卦绣,并且使它們可以相互替換耐量。
目的:將算法的使用算法的實(shí)現(xiàn)分離開來。
一個(gè)基于策略模式的程序至少由兩部分組成迎卤。第一部分是一組策略類(可變)拴鸵,策略類封裝了具體的算法,并負(fù)責(zé)具體的計(jì)算過程。第二個(gè)部分是環(huán)境類Context(不變)劲藐,Context接收客戶的請求八堡,隨后將請求委托給某一個(gè)策略類。要做到這一點(diǎn)聘芜,說明Context中要維持對某個(gè)策略對象的引用兄渺。
3)代理模式
定義:為一個(gè)對象提供一個(gè)代用品或占位符,以便控制對它的訪問汰现。
常用的虛擬代理形式:某一個(gè)花銷很大的操作挂谍,可以通過虛擬代理的方式延遲到這種需要它的時(shí)候才去創(chuàng)建(例,使用虛擬代理實(shí)現(xiàn)圖片懶加載)
圖片懶加載的方式:先通過一張loading圖占位瞎饲,然后通過異步的方式加載圖片口叙,等圖片加載好了再把完成的圖片加載到img標(biāo)簽里面。
使用代理模式實(shí)現(xiàn)圖片懶加載的優(yōu)點(diǎn)還有符合單一職責(zé)原則嗅战。減少一個(gè)類或方法的粒度和耦合度妄田。
4)中介者模式
定義:通過一個(gè)中介者對象,其他所有的相關(guān)對象都通過該中介者對象來通信驮捍,而不是相互引用疟呐,當(dāng)其中的一個(gè)對象發(fā)生改變時(shí),只需要通知中介者對象即可东且。通過中介者模式可以解除對象與對象之間的緊耦合關(guān)系启具。
適用場景:例如,購物車需求珊泳,存在商品選擇表單鲁冯,顏色選擇表單,購買數(shù)量表單等等旨椒,都會(huì)觸發(fā)change事件晓褪,那么可以通過中介者來轉(zhuǎn)發(fā)處理這些事件,實(shí)現(xiàn)各個(gè)事件間的解耦综慎,僅僅維護(hù)中介者對象即可。
5)裝飾著模式
定義:在不改變對象自身的基礎(chǔ)上勤庐,在程序運(yùn)行期間給對象動(dòng)態(tài)的添加方法示惊。
適用場景:原有方法維持不變,在原有的方法上再掛載其他方法來滿足現(xiàn)有需求愉镰;函數(shù)的解耦米罚,將函數(shù)拆分成多個(gè)可復(fù)用的函數(shù),再將拆分出來的函數(shù)掛載到某個(gè)函數(shù)上丈探,實(shí)現(xiàn)相同的效果但增強(qiáng)了復(fù)用性录择。
24、JavaScript的運(yùn)行機(jī)制
JavaScript在執(zhí)行的過程中會(huì)產(chǎn)生執(zhí)行環(huán)境,這些執(zhí)行環(huán)境會(huì)被順利的加入到執(zhí)行棧中隘竭。如果遇到異步的代碼塘秦,會(huì)被掛起并加入到Task(有多種task)隊(duì)列中。一旦執(zhí)行棧為空动看,Event Loop就會(huì)從Task隊(duì)列中拿出需要執(zhí)行的代碼并放入執(zhí)行棧中執(zhí)行尊剔。
不同的任務(wù)源會(huì)被分到不同的Task隊(duì)列中,任務(wù)源可以分為微任務(wù)和宏任務(wù)菱皆。
正確的一次Event Loop順序是這樣的:
1)執(zhí)行同步代碼须误,這屬于宏任務(wù)
2)執(zhí)行棧為空,查詢是否有微任務(wù)需要執(zhí)行
3)執(zhí)行所有的微任務(wù)
4)渲染UI
5)開始下一輪Event Loop仇轻,執(zhí)行宏任務(wù)中的異步代碼
由此Event Loop順序可知整吆,如果宏任務(wù)中的異步代碼由大量的計(jì)算并且需要操作Dom的話,為了更快的界面響應(yīng)裤唠,我們可以把操作Dom放入微任務(wù)中垃瞧。
25、Node.js的Event Loop
Node.js也是單線程的Event Loop船庇,但是它的運(yùn)行機(jī)制不同于瀏覽器環(huán)境吭产。
Node.js運(yùn)行機(jī)制如下:
1)V8引擎解析JavaScript腳本
2)解析后的代碼,調(diào)用Node API
3)libuv庫負(fù)責(zé)Node API的執(zhí)行鸭轮。它將不同的任務(wù)分配給不同的線程臣淤,形成一個(gè)Even Loop(事件循環(huán)),以異步的方式將任務(wù)的執(zhí)行結(jié)果返回給V8引擎
4)V8引擎再將結(jié)果返回給用戶
Node.js提供的與”任務(wù)隊(duì)列“有關(guān)的方法:
setTimeout與setInterval
process.nextTick方法可以在當(dāng)前”執(zhí)行椙砸“的尾部---下一次Event Loop(主線程讀取”任務(wù)隊(duì)列“)之前---觸發(fā)回調(diào)函數(shù)邑蒋。即,它指定的任務(wù)總是發(fā)生在所有異步任務(wù)之前按厘。
setImmediate方法則是在當(dāng)前”任務(wù)隊(duì)列“的尾部添加事件医吊。即,它指定的任務(wù)是在下一次Even Loop時(shí)執(zhí)行逮京。
26卿堂、什么是ajax?作用是什么懒棉?工作原理草描?原生js的ajax請求有幾個(gè)步驟?分別是什么策严?
ajax是異步的JavaScript和xml穗慕。
ajax是一種用于創(chuàng)建快速動(dòng)態(tài)網(wǎng)頁的技術(shù)。ajax用來與后臺(tái)交互妻导。
ajax的工作原理相當(dāng)于在用戶和服務(wù)器之間加了一個(gè)中間層(ajax引擎)逛绵,使用戶操作與服務(wù)器響應(yīng)異步化怀各。并不是所有的用戶請求都提交給服務(wù)器,像一些數(shù)據(jù)驗(yàn)證和數(shù)據(jù)處理等都交給Ajax引擎自己來做术浪,只有確定需要從服務(wù)器讀取新數(shù)據(jù)時(shí)再由Ajax引擎代為向服務(wù)器提交請求瓢对。
ajax,實(shí)現(xiàn)了客戶端與服務(wù)器進(jìn)行數(shù)據(jù)交流過程。使用技術(shù)的好處是:不用頁面刷新添吗,并且在等待頁面?zhèn)鬏敂?shù)據(jù)的同時(shí)可以進(jìn)行其他操作沥曹。
步驟:
1)//創(chuàng)建XMLHttpRequest對象
var xhr = new XMLHttpRequest( );?
2)//規(guī)定請求的類型,URL以及是否異步處理請求
xhr.open ('GET', url, true)碟联,第三個(gè)參數(shù)為true,表示不等待妓美,直接返回異步獲取鲤孵;為false,表示等待有返回?cái)?shù)據(jù)的時(shí)候繼續(xù)往下走壶栋,還沒有得到數(shù)據(jù)的時(shí)候就會(huì)卡在那里,直到獲取數(shù)據(jù)為止普监。
3)//發(fā)送信息至服務(wù)器時(shí)內(nèi)容編碼類型
xhr.setRequestHeader('Content-type', 'appliaction/x-www-form-urlencode');
4)//發(fā)送請求
xhr.send(null);
5)// 接收服務(wù)器響應(yīng)數(shù)據(jù)
xhr.onreadystatechange = function( ){
if (obj.readyState == 4 && (obj.status == 200 || obj.status == 304)) { }
}
1)當(dāng)readystate值從一個(gè)值變成另一個(gè)值贵试,都會(huì)觸發(fā)readystatechange事件
2)當(dāng)readystate==4時(shí),表示已經(jīng)接收到全部響應(yīng)數(shù)據(jù)
3)當(dāng)status==200時(shí)凯正,表示服務(wù)器成功返回頁面和數(shù)據(jù)
4)如果2)毙玻,3)內(nèi)容同時(shí)滿足,則可以以通過xhr.responsetext廊散,獲得服務(wù)器返回的內(nèi)容
ajax運(yùn)行步驟與狀態(tài)值說明:
? ? ? 在ajax實(shí)際運(yùn)行當(dāng)中桑滩,對于訪問XMLHttpRequest(XHR)時(shí)并不是一次完成的,而是分別經(jīng)歷了多種狀態(tài)后取得的結(jié)果允睹,對于這種狀態(tài)在Ajax中共有5種运准,分別是:
0---(未初始化)還沒有調(diào)用send( )方法
1---(載入)已調(diào)用send( )方法,正在發(fā)送請求
2---(載入完成)send( )方法執(zhí)行完成
3---(交互)正在解析響應(yīng)內(nèi)容
4---(完成)響應(yīng)內(nèi)容解析完成缭受,可以在客戶端調(diào)用了
對于上面的狀態(tài)胁澳,其中”0“狀態(tài)是在定義后自動(dòng)具有的狀態(tài)值,而對于成功訪問的狀態(tài)(得到信息)我們大多數(shù)采用”4“進(jìn)行判斷米者。
響應(yīng)狀態(tài)碼:
200---請求成功韭畸,正常返回?cái)?shù)據(jù)
301---刪除請求數(shù)據(jù),重定向
304---該資源在上次請求之后沒有任何修改(通常用于瀏覽器的緩存機(jī)制)
401---請求要求身份驗(yàn)證
403---服務(wù)器拒絕請求
404---服務(wù)器找不到請求的網(wǎng)頁
408---服務(wù)器等候請求時(shí)發(fā)生請求超時(shí)
500---服務(wù)器內(nèi)部錯(cuò)誤塘雳,無法完成請求
27陆盘、跨標(biāo)簽頁通訊
1)本地存儲(chǔ):localStorage
// 頁面A發(fā)送事件
function sendMsg(text) {
? ? window.localStorage.setItem('msg',text);
}
// 頁面B接收事件
window.addEventListener('storage', function (evt) {
? ? if(evt.key==='msg')
? ? ? console.log(evt.newValue);
});
注意:重復(fù)設(shè)置相同的鍵值不會(huì)再次觸發(fā)事件
2)使用cookie+setInterval,將要傳遞的信息存儲(chǔ)在cookie里面败明,然后每隔一定時(shí)間讀取cookie信息來實(shí)現(xiàn)。
<input? type="button"? id="butOk"? value="信息">
// a頁面
var mess=document.getElementById("butOk").value();? ?
document.cookie="mess="+mess;
// b頁面
// 獲取Cookie天的內(nèi)容?
function getKey(key) {?
? ? return JSON.parse("{\""+ document.cookie.replace(/;\s+/gim,"\",\"").replace(/=/gim, "\":\"") +"\"}")[key];?
}?
//每隔1秒獲取Cookie的內(nèi)容?
setInterval(function(){?
? ? console.log(getKey("mess"));?
},1000);
Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setDomain(".helloweenvsfei.com");? ? ? ? ? // 設(shè)置域名
cookie.setPath("/");? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 設(shè)置路徑
cookie.setMaxAge(Integer.MAX_VALUE);? ? ? ? ? ? ? // 設(shè)置有效期
cookie.setSecure(true);? ? ? ? ? ? ? ? ? ? ? ? ? // 設(shè)置安全屬性
response.addCookie(cookie);? ? ? ? ? ? ? ? ? ? ? // 輸出到客戶端
28太防、防抖動(dòng)與節(jié)流的區(qū)別:
1)防抖動(dòng)是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行妻顶。
應(yīng)用場景:使用在用戶輸入停止一段時(shí)間過去后再去獲取數(shù)據(jù)酸员,而不是每次輸入都去獲取。
// 實(shí)現(xiàn)一個(gè)防抖函數(shù)讳嘱,在規(guī)定時(shí)間內(nèi)未觸發(fā)第二次則執(zhí)行
function debounce(fn, delay){
? ? // 利用閉包保存定時(shí)器
? ? let timer = null
? ? return function (){
? ? ? ? let context = this
? ? ? ? let arg = arguments
? ? ? ? // 在規(guī)定時(shí)間內(nèi)再次觸發(fā)會(huì)先清除定時(shí)器后再重設(shè)定時(shí)器
? ? ? ? clearTimeout(timer)
? ? ? ? timer = setTimeout(function(){
? ? ? ? ? ? fn.apply(context,arg)
? ? ? ? }, delay)
? ? }
}
function fn(){
? ? console.log('防抖')
}
addEventListener('scroll', debounce(fn, 1000))
2)節(jié)流是將多次執(zhí)行變成每隔一段時(shí)間執(zhí)行幔嗦。
應(yīng)用場景:懶加載時(shí)要監(jiān)聽計(jì)算滾動(dòng)條的位置,但不必每次滑動(dòng)都觸發(fā)沥潭,可以降低計(jì)算的頻率邀泉,而不必去浪費(fèi)資源;
另外還有做商品預(yù)覽圖的放大鏡效果時(shí)钝鸽,不必每次鼠標(biāo)移動(dòng)都計(jì)算位置汇恤。
// 實(shí)現(xiàn)一個(gè)節(jié)流函數(shù),在規(guī)定時(shí)間內(nèi)只觸發(fā)一次
function throttle(fn,delay){
? ? // 利用閉包保存時(shí)間
? ? let prev = Date.now()
? return function(){
? ? ? ? let context = this
? ? ? ? let arg = arguments
? ? ? ? let now = Date.now()
? ? ? ? if(now - prev >= delay){
? ? ? ? ? ? fn.apply(context, arg)
? ? ? ? ? ? prev = Date.now()
? ? ? ? }
? ? }
}
function fn(){
? ? console.log('節(jié)流')
}
addEventListener('scroll', throttle(fn, 1000))
29拔恰、瀏覽器渲染過程:
1)瀏覽器將獲取的HTML文檔并解析成DOM樹
2)處理CSS標(biāo)記因谎,構(gòu)成層疊樣式表模型CSSDOM(css Object Model)
3)將DOM和CSSDOM合并為渲染樹(rending tree)將會(huì)被創(chuàng)建,代表一系列將被渲染的對象
4)渲染樹的每個(gè)元素包含的內(nèi)容都是計(jì)算過的颜懊,它被稱為布局layout财岔。瀏覽器使用一種流式處理的方法,只需要一次pass繪制操作就可以布局所有的元素
5)將渲染樹的各個(gè)節(jié)點(diǎn)繪制到屏幕上河爹,這一步被稱為繪制painting
30匠璧、計(jì)算機(jī)網(wǎng)絡(luò)TCP和UDP的區(qū)別:
1)TCP面向連接(如打電話要先撥號(hào)建立連接);UDP是無連接的咸这,即發(fā)送數(shù)據(jù)之前不需要建立連接
2)TCP提供可靠的服務(wù)夷恍。即,通過TCP連接傳送的數(shù)據(jù)炊苫,無差錯(cuò)裁厅,不丟失,不重復(fù)侨艾,且按序到達(dá)执虹;UDP盡最大努力交付,即不保證可靠交付唠梨。TCP通過校驗(yàn)袋励,重傳控制,序號(hào)標(biāo)識(shí)当叭,滑動(dòng)窗口茬故,確認(rèn)應(yīng)答實(shí)現(xiàn)可靠傳輸。如蚁鳖,丟包時(shí)的重發(fā)控制磺芭,還可以對次序亂掉的分包進(jìn)行順序控制。
3)UDP具有較好的實(shí)時(shí)性醉箕,工作效率比TCP高钾腺,適用于對高速傳輸和實(shí)時(shí)性有較高的通信或廣播通信徙垫。
4)每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對一放棒,一對多姻报,多對一和多對多的交互通信
5)TCP系統(tǒng)資源要求較多,UDP對系統(tǒng)資源要求較少
31间螟、進(jìn)程和線程的區(qū)別:
1)一個(gè)程序至少有一個(gè)進(jìn)程吴旋,一個(gè)進(jìn)程至少有一個(gè)線程
2)線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高
3)進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元厢破,而多個(gè)線程共享內(nèi)存荣瑟,從而極大的提高了程序的運(yùn)行效率。
4)線程在執(zhí)行過程中與進(jìn)程還是有區(qū)別的溉奕。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口褂傀,順序執(zhí)行序列和程序的出口。但是線程不能獨(dú)立執(zhí)行加勤,必須依存在應(yīng)用程序中仙辟,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。
5)從邏輯角度來看鳄梅,多線程的意義在于一個(gè)應(yīng)用程序中叠国,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。但操作系統(tǒng)并沒有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用戴尸,來實(shí)現(xiàn)進(jìn)程調(diào)度和管理以及資源分配粟焊。
32、如何讓事件先冒泡后捕獲:
在Dom標(biāo)準(zhǔn)事件模型中孙蒙,是先捕獲后冒泡项棠。但是如果要實(shí)現(xiàn)先冒泡后捕獲的效果,對于同一個(gè)事件挎峦,監(jiān)聽捕獲和冒泡香追,分別對應(yīng)相應(yīng)的處理函數(shù),監(jiān)聽到捕獲事件坦胶,先暫緩執(zhí)行透典,直到冒泡事件被捕獲后再執(zhí)行捕獲之間。
33顿苇、事件委托:
簡介:事件委托指的是峭咒,不在事件的發(fā)生地(直接dom)上設(shè)置監(jiān)聽函數(shù),而是在其父元素上設(shè)置監(jiān)聽函數(shù)纪岁,通過事件冒泡凑队,父元素可以監(jiān)聽到子元素上事件的觸發(fā),通過判斷事件發(fā)生元素Dom的類型幔翰,來做出不同的響應(yīng)顽决。
舉例:最經(jīng)典的就是ul和li標(biāo)簽的事件監(jiān)聽短条,比如我們在添加事件時(shí)候导匣,采用事件委托機(jī)制才菠,不會(huì)再li標(biāo)簽上直接添加,而是再ul父元素上添加贡定。
好處:比較合適動(dòng)態(tài)元素的綁定赋访,新添加的子元素也會(huì)有監(jiān)聽函數(shù),也可以有事件觸發(fā)機(jī)制缓待。
34蚓耽、圖片的懶加載和預(yù)加載
預(yù)加載:提前加載圖片,當(dāng)用戶需要查看時(shí)可直接從本地緩存中渲染‘
懶加載:懶加載的主要目的時(shí)作為服務(wù)器前端的優(yōu)化旋炒,減少請求數(shù)或延遲請求數(shù)
兩種技術(shù)的本質(zhì):兩者的行為時(shí)相反的步悠,一個(gè)時(shí)提前加載,一個(gè)是遲緩甚至不加載
懶加載對服務(wù)器前端有一定的緩解壓力作用瘫镇,預(yù)加載則會(huì)增加服務(wù)器前端壓力
35鼎兽、函數(shù)柯里化:
屬于高階函數(shù)應(yīng)用,傳遞給函數(shù)部分參數(shù)來調(diào)用柯里化函數(shù)铣除,讓它返回一個(gè)函數(shù)去處理剩下的參數(shù)谚咬。
把接收多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換成接收一個(gè)單一參數(shù)的函數(shù)。
var foo = fucntion(x){
return function(y){
return x+y;
}
}
foo(3)(4)? // 輸出為7
36尚粘、requestAnimationFrame是怎么使用的择卦?
requestAnimationFrame( )方法告訴瀏覽器,希望執(zhí)行動(dòng)畫并請求瀏覽器在下一次重繪之前調(diào)用指定的函數(shù)來更新動(dòng)畫郎嫁。該方法使用一個(gè)回調(diào)函數(shù)作為參數(shù)秉继,這個(gè)回調(diào)函數(shù)會(huì)在瀏覽器重繪之前調(diào)用
37、PWA全稱是Progressive Web App泽铛,即漸進(jìn)式WEB應(yīng)用尚辑。一個(gè)PWA應(yīng)用首先是一個(gè)網(wǎng)頁,可以通過Web技術(shù)編寫出一個(gè)網(wǎng)頁應(yīng)用厚宰。隨后添加上App Manifest和Service Worker來實(shí)現(xiàn)PWA的安裝和離線等功能腌巾。
38、數(shù)據(jù)屬性與訪問器屬性的區(qū)別:
在JS中對象的屬性分為兩種類型:數(shù)據(jù)屬性和訪問器屬性铲觉。
1)數(shù)據(jù)屬性:它包含的是一個(gè)數(shù)據(jù)值的位置澈蝙,在這可以對數(shù)據(jù)值進(jìn)行讀寫。
包含四個(gè)特性:
configurable:表示能否通過delete刪除屬性從而重新定義屬性撵幽,能否修改屬性的特性灯荧,或能否把屬性修改為訪問器屬性,默認(rèn)為true
enumerable:表示能否通過for-in循環(huán)返回屬性
writable:表示能否修改屬性的值
value:包含該屬性的數(shù)據(jù)值盐杂。默認(rèn)為undefined
修改數(shù)據(jù)屬性的默認(rèn)特性: 使用Object.defineProperty( )方法逗载,這個(gè)方法有三個(gè)參數(shù):屬性所在的對象哆窿,屬性名,一個(gè)描述符對象厉斟。
2)訪問器屬性:這個(gè)屬性不包含數(shù)據(jù)值挚躯,包含的是一對get和set方法,在讀寫訪問器屬性時(shí)擦秽,就是通過這兩個(gè)方法來進(jìn)行操作處理的码荔。
包含的四個(gè)特性:
configurable:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性感挥,或能否把屬性修改為訪問器屬性缩搅,默認(rèn)為false
enumerable:表示能否通過for-in循環(huán)返回屬性,默認(rèn)為false
Get:在讀取屬性時(shí)調(diào)用的函數(shù)触幼,默認(rèn)值為undefined
Set:在寫入屬性時(shí)調(diào)用的函數(shù)硼瓣,默認(rèn)值為undefined
注意:訪問器屬性不能直接定義,要通過Object.defineProperty( )這個(gè)方法來定義置谦。
? ? ? ? 后續(xù)需要對該屬性進(jìn)行delete操作等堂鲤,就需要定義訪問器屬性時(shí),將這個(gè)特性設(shè)置為true霉祸。
39筑累、Proxy 對象用于定義基本操作的自定義行為(如,屬性查找丝蹭、賦值慢宗、枚舉、函數(shù)調(diào)用等)奔穿。
const p = new Proxy(target, handler)镜沽;
target,要使用Proxy包裝的目標(biāo)對象(可以時(shí)任何類型的對象贱田,包括原生數(shù)組缅茉,函數(shù),甚至另一個(gè)代理)男摧。
handle蔬墩,一個(gè)通常以函數(shù)作為屬性的對象,各屬性中的函數(shù)分別定義了在執(zhí)行各種操作時(shí)代理的行為耗拓。
Proxy.revocable( )---創(chuàng)建一個(gè)可撤銷的proxy對象拇颅。
40、Echarts的應(yīng)用:
1)常見配置:
title:{...}-----標(biāo)題
legend:{...}-----圖標(biāo)
grid:{...}-----布局乔询,坐標(biāo)面板位置
xAxis:{...}-----X軸
yAxis:{...}-----Y軸
tooltip:{...}-----圖標(biāo)懸停的提示內(nèi)容
toolBox:{...}-----工具欄組件樟插,內(nèi)置有導(dǎo)出圖片,數(shù)據(jù)視圖,動(dòng)態(tài)類型切換黄锤,數(shù)據(jù)區(qū)域縮放搪缨,重置5個(gè)工具
series:[...]-----系列,它是一個(gè)數(shù)組鸵熟,里面的元素是一個(gè)對象副编,每個(gè)對象就是一組數(shù)據(jù)的所有信息
2)echarts的API交互
echarts:{...}----主要時(shí)獲取或設(shè)置全局屬性對象API相關(guān)的
echartsInstance:{...}-----主要是獲取或設(shè)置圖標(biāo)echart.init對象相關(guān)的API屬性
action:{...}-----主要是包含一些event事件和一些數(shù)據(jù)可視化的行為設(shè)置例如高亮,tooltip位置設(shè)置等
events:{...}----主要是圖表的一些觸發(fā)事件
3)echarts常見問題解決
a旅赢、當(dāng)X軸上面要渲染的數(shù)據(jù)太多的時(shí)候就會(huì)出現(xiàn)只渲染出來一部分齿桃,但是圖標(biāo)中的數(shù)據(jù)顯示(比如說柱狀圖中的每個(gè)柱子)又會(huì)自動(dòng)的進(jìn)行寬度的縮放,所以會(huì)導(dǎo)致X軸與圖中的信息不相匹配的問題煮盼,解決的方法是在X軸設(shè)置axisLable:{interval:0}這個(gè)屬性問題就可以解決了,Y軸的使用相同的方法带污。
b僵控、為了使echart圖標(biāo)隨著瀏覽器的大小發(fā)生響應(yīng)式變化,所以需要在設(shè)置配置之前添加window.onresize = echart.resize;
4)調(diào)用實(shí)例myChart的setOption( )方法鱼冀,將option這個(gè)對象搞定到自己身上报破。
41、Echarts與D3的區(qū)別:
Echarts:1)封裝好的方法直接調(diào)用
2)兼容到IE6以及以上的所有主流瀏覽器
3)echarts通過canvas來繪制圖形
4)封裝好的千绪,直接用充易,不能修改
D3:1)太底層,學(xué)習(xí)成本大
2)兼容到IE9以上以及所有的主瀏覽器
3)D3通過svg來繪制圖形
4)可以自定義事件
42荸型、Svg與Canvas的區(qū)別:
Svg:1)不依賴分辨率
2)基于xml繪制圖形盹靴,可以操作dom
3)支持事件處理
4)復(fù)雜度高,會(huì)減慢頁面的渲染速度
Canvas:1)依賴分辨率
2)基于js繪制圖形
3)不支持事件處理器
4)能以png/jpg的格式保存圖片
43瑞妇、網(wǎng)絡(luò)協(xié)議:
1)IP協(xié)議(尋址)47.95.70.218
2)IP協(xié)議之上稿静,使用Tcp來確保數(shù)據(jù)的完整有序
三次握手,滑動(dòng)窗口辕狰,慢啟動(dòng)改备,揮手,分包蔓倍,重發(fā)
3)Tcp協(xié)議之上悬钳,使用http協(xié)議來作為網(wǎng)頁傳輸?shù)膮f(xié)議(應(yīng)用層)
44、XSS防御總結(jié):
原理:XSS攻擊涉及到三方偶翅,攻擊者默勾、用戶、web serve倒堕。用戶是通過瀏覽器來訪問web server上的網(wǎng)頁灾测,XSS攻擊就是攻擊者通過各種辦法,在用戶訪問的網(wǎng)頁中插入自己的腳本,讓其在用戶訪問網(wǎng)頁時(shí)在其瀏覽器中進(jìn)行執(zhí)行媳搪。攻擊者通過插入的腳本的執(zhí)行铭段,來獲取用戶的信息,如cookie秦爆,發(fā)送到攻擊者自己的網(wǎng)站(跨站了)序愚。所以稱為跨站腳本攻擊。
分類:XSS可以分為反射型XSS和持久型XSS等限,還有DOM Based XSS爸吮。
(XSS,就是在用戶的瀏覽器中執(zhí)行攻擊者自己定制的腳本望门。)
1)反射型XSS形娇,也就是非持久性XSS。用戶點(diǎn)擊攻擊連接筹误,服務(wù)器解析后響應(yīng)桐早,在返回的響應(yīng)內(nèi)容中出現(xiàn)攻擊者的XSS代碼,被瀏覽器執(zhí)行厨剪。一來一去哄酝,XSS攻擊腳本被web server反射回來給瀏覽器,所以稱為反射型XSS祷膳。
特點(diǎn):XSS攻擊代碼非持久性陶衅,也就是沒有保存在web server中,而是出現(xiàn)在URL地址中直晨;一般時(shí)攻擊者通過郵件搀军,聊天軟件等等方式發(fā)送攻擊URL,然后用戶點(diǎn)擊來達(dá)到攻擊目的抡秆。
XSS 攻擊的防御:對輸入(和URL參數(shù))進(jìn)行過濾奕巍,對輸出進(jìn)行編碼。
45儒士、webSocket:
http協(xié)議有一個(gè)缺陷的止,通信只能由客戶端發(fā)起。做不到服務(wù)器主動(dòng)向客戶端推送信息着撩。這種單向請求诅福,注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶端要獲知拖叙,只能使用“輪詢”氓润,每隔一段時(shí)間,就發(fā)出一個(gè)詢問薯鳍,了解服務(wù)器有沒有新的信息咖气。最典型的場景就是聊天室。輪詢的效率低,非常浪費(fèi)資源崩溪。
webSocket是HTML5開始提供的一種在單個(gè)TCP連接上進(jìn)行全雙工通訊的協(xié)議浅役。webSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)伶唯。在webSocket API中觉既,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接乳幸,并進(jìn)行雙向數(shù)據(jù)傳輸瞪讼。它最大的特點(diǎn)就是,服務(wù)器可以主動(dòng)向客戶端推送信息粹断,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息符欠,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種姿染。
特點(diǎn):
1)建立在TCP協(xié)議之上背亥,服務(wù)器端的實(shí)現(xiàn)比較容易
2)與http有良好的兼容性,默認(rèn)端口也是80與443悬赏,并且握手階段采用http協(xié)議,因此握手時(shí)不容易屏蔽娄徊,能通過各種http代理服務(wù)器
3)數(shù)據(jù)格式比較輕量闽颇,性能開銷小,通信高效
4)可以發(fā)送文本寄锐,也可以發(fā)送二進(jìn)制數(shù)據(jù)
5)沒有同源限制兵多,客戶端可以與任意服務(wù)器通信
6)協(xié)議標(biāo)識(shí)符是WS(如果加密,則為wss)橄仆,服務(wù)器網(wǎng)站就是URL
用法:
// webSocket對象作為一個(gè)構(gòu)造函數(shù)剩膘,用于新建webSocket實(shí)例,實(shí)行下面語句后盆顾,客戶端就會(huì)與服務(wù)器進(jìn)行連接怠褐。
var ws = new WebSocket("ws://localhost:8080");?
ws.onopen = function(evt) {? // 指定連接成功后的回調(diào)函數(shù)
? console.log("Connection open ...");
? ws.send("Hello WebSockets!"); ////? send( )方法用于向服務(wù)器發(fā)送數(shù)據(jù)
};
// 用于指定收到服務(wù)器數(shù)據(jù)后的回調(diào)函數(shù),除了動(dòng)態(tài)判斷收到的數(shù)據(jù)類型您宪,也可以用binaryType屬性奈懒,顯示指定收到的二進(jìn)制數(shù)據(jù)類型
ws.onmessage = function(evt) {?
? console.log( "Received Message: " + evt.data);
? ws.close();
};
ws.onclose = function(evt) {? // 用于指定連接關(guān)閉后的回調(diào)函數(shù)
? console.log("Connection closed.");
};? ? ?
46、web前端性能優(yōu)化常見方法:
內(nèi)容優(yōu)化:
? ? ? 1)減少HTTP請求數(shù)宪巨,因?yàn)橐粋€(gè)完整的請求要經(jīng)過DNS尋址磷杏,與服務(wù)器建立連接,發(fā)送數(shù)據(jù)捏卓,等待服務(wù)器響應(yīng)极祸,接收數(shù)據(jù)這樣一個(gè)消耗時(shí)間成本和資源成本的復(fù)雜的過程。? 常見方法:合并多個(gè)CSS文件和JS文件,利用雪碧圖整合圖像遥金,Inline Image(使用data:URL scheme在實(shí)際的頁面嵌入圖像數(shù)據(jù))浴捆,合理設(shè)置HTTP緩存等。
? ? ? 2)減少DNS查找
? ? ? 3)避免重定向
? ? ? 4)使用Ajax緩存
? ? ? 5)延遲加載組件汰规,預(yù)加載組件
? ? ? 6)減少DOM元素?cái)?shù)量:頁面中存在大量DOM 元素汤功,會(huì)導(dǎo)致JavaScript遍歷DOM的效率變慢
? ? ? 7)最小化iframe的數(shù)量:iframes提供了一個(gè)簡單的方式把一個(gè)網(wǎng)站的內(nèi)容嵌入到另一個(gè)網(wǎng)站中。但其創(chuàng)建速度比其他包括JavaScript和CSS的DOM元素的創(chuàng)建慢了1-2個(gè)數(shù)量級溜哮。
? ? ? 8)避免404:HTTP請求時(shí)間消耗是很大的滔金,因此使用HTTP請求來獲得一個(gè)沒有用處的響應(yīng)(例如404沒有找到頁面)是完全沒有必要的,它只會(huì)降低用戶體驗(yàn)而不會(huì)有一點(diǎn)好處茂嗓。
服務(wù)器優(yōu)化:
? ? ? 1)使用內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN):把網(wǎng)站內(nèi)容分散到多個(gè)餐茵,處于不同地域位置的服務(wù)器上可以加快下載速度。
? ? ? 2)gzip壓縮
? ? ? 3)設(shè)置Etag:Etags(Entity tags,實(shí)體標(biāo)簽)是web服務(wù)器和瀏覽器用于判斷瀏覽器緩存中的內(nèi)容和服務(wù)器中的原始內(nèi)容是否匹配的一種機(jī)制
? ? ? 4)提前刷新緩沖區(qū)
? ? ? 5)對Ajax請求使用GET方法
? ? ? 6)避免空的圖像src
Cookie優(yōu)化:
? ? ? 1)減少Cookie大小
? ? ? 2)針對web組件使用域名無關(guān)的Cookie
CSS優(yōu)化:
? ? ? 1)將css代碼放在HTML頁面的頂部
? ? ? 2)避免使用css表達(dá)式
? ? ? ? ? ? ? 3)使用<link>來代替@import
? ? ? 4)避免使用Filters
JavaScript優(yōu)化:
? ? ? 1)將JavaScript腳本放在頁面的底部
? ? ? 2)將JavaScript和CSS作為外部文件來引用述吸,在實(shí)際應(yīng)用中使用外部文件可以提高頁面速度忿族,因?yàn)镴avaScript和CSS文件都能在瀏覽器中產(chǎn)生緩存
? ? ? 3)縮小JavaScript和CSS
? ? ? 4)刪除重復(fù)的腳本
? ? ? 5)最小化DOM的訪問:使用JavaScript訪問DOM元素比較慢
? 6)JavaScript代碼注意:謹(jǐn)慎使用with,避免使用eval Function函數(shù)蝌矛,減少作用域鏈查找(eval將對應(yīng)的字符串解析成js并執(zhí)行道批,應(yīng)該避免使用js,因?yàn)榉浅:男阅埽?次入撒,一次解析成js隆豹,一次執(zhí)行))
圖像優(yōu)化:
? ? ? 1)優(yōu)化圖片大小
? ? ? 2)通過CSS Sprites優(yōu)化圖片
? ? ? 3)不要在HTML中使用縮放圖片
? ? ? 4)favicon.ico要小而且可緩存
移動(dòng)客戶端:
? ? ? 1)保持單個(gè)內(nèi)容小于25KB
? ? ? 2)打包組建成符合文檔
47、JS里的垃圾回收機(jī)制是什么茅逮,常用的是哪種璃赡,怎么處理的?
JS的垃圾回收機(jī)制是為了以防內(nèi)存泄漏献雅。內(nèi)存泄漏的含義就是當(dāng)已經(jīng)不需要某塊內(nèi)存時(shí)這塊內(nèi)存還存在著碉考,垃圾回收機(jī)制就是間歇的不定期的尋找到不再使用的變量,并釋放掉它們所指向的內(nèi)存挺身。
JS中最常見的垃圾回收方式是標(biāo)記清除侯谁。
工作原理:是當(dāng)變量進(jìn)入環(huán)境時(shí),將這個(gè)變量標(biāo)記為“進(jìn)入環(huán)境”瞒渠。當(dāng)變量離開環(huán)境時(shí)良蒸,則將其標(biāo)記為“離開環(huán)境”。標(biāo)記“離開環(huán)境”的就回收內(nèi)存伍玖。
工作流程:
1)垃圾回收器嫩痰,在運(yùn)行的時(shí)候會(huì)給存儲(chǔ)在內(nèi)存中的所有變量都加上標(biāo)記。
2)去掉環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標(biāo)記窍箍。
3)再被加上標(biāo)記的會(huì)被視為準(zhǔn)備刪除的變量串纺。
4)垃圾回收器完成內(nèi)存清除工作丽旅,銷毀那些帶標(biāo)記的值并回收他們所占用的內(nèi)存空間。
JS中的內(nèi)存泄漏:
程序不需要的內(nèi)存纺棺,由于某些原因其不會(huì)返回到操作系統(tǒng)或者可用內(nèi)存中榄笙。內(nèi)存泄漏會(huì)導(dǎo)致(運(yùn)行緩慢,高延遲祷蝌,崩潰)的問題茅撞。
常見的導(dǎo)致內(nèi)存泄漏的原因有:
1)意外的全局變量
2)被遺忘的計(jì)時(shí)器或回調(diào)函數(shù)
3)脫離文檔的DOM的引用
4)閉包
48、for-in和for-of的區(qū)別:
1)循環(huán)對象屬性的時(shí)候巨朦,使用for...in米丘,遍歷數(shù)組的時(shí)候使用for...of
2)for...in循環(huán)出的是key,for...of循環(huán)出的是value
3)for...of是ES6新引入的特性糊啡。修復(fù)了ES5引入的for...in的不足
4)for...of不能循環(huán)普通的對象拄查,需要通過和Object.keys( )搭配使用
49、Math.min( )和Math.max( )大小比較:
Math.min( )? <? Math.max( )
Math.min( )如果沒有參數(shù)棚蓄,則返回Infinity堕扶。Infinity是JavaScript中全局對象的一個(gè)屬性,在瀏覽器環(huán)境中就是window對象的一個(gè)屬性梭依,表示無窮大稍算。
Math.max( )沒有傳遞參數(shù)時(shí)返回的是-Infinity。因此Math.min( ) 要比Math.max( )大役拴。
50邪蛔、前端JS加密方法:
1)base64加密
2)md5加密
3)sha1加密