1.Ajax原理
Ajax的原理簡單來說是在用戶和服務(wù)器之間加了—個中間層(AJAX引擎)冒萄,通過XmlHttpRequest對象來向服務(wù)器發(fā)異步請求,從服務(wù)器獲得數(shù)據(jù)荔泳,然后用javascript來操作DOM而更新頁面蕉饼。使用戶操作與服務(wù)器響應(yīng)異步化。這其中最關(guān)鍵的一步就是從服務(wù)器獲得請求數(shù)據(jù)
Ajax的過程只涉及JavaScript玛歌、XMLHttpRequest和DOM昧港。XMLHttpRequest是ajax的核心機制
ajax 有那些優(yōu)缺點?
優(yōu)點:
通過異步模式,提升了用戶體驗.
優(yōu)化了瀏覽器和服務(wù)器之間的傳輸支子,減少不必要的數(shù)據(jù)往返创肥,減少了帶寬占用.
Ajax在客戶端運行,承擔(dān)了一部分本來由服務(wù)器承擔(dān)的工作值朋,減少了大用戶量下的服務(wù)器負(fù)載叹侄。
Ajax可以實現(xiàn)動態(tài)不刷新(局部刷新)
缺點:
安全問題?AJAX暴露了與服務(wù)器交互的細(xì)節(jié)。
對搜索引擎的支持比較弱昨登。
不容易調(diào)試趾代。
2 異步加載JS的方式有哪些?
設(shè)置<script>屬性 async="async" (一旦腳本可用丰辣,則會異步執(zhí)行)
動態(tài)創(chuàng)建?script DOM:document.createElement('script');
XmlHttpRequest?腳本注入
異步加載庫?LABjs
模塊加載器?Sea.js
3 那些操作會造成內(nèi)存泄漏稽坤?
JavaScript 內(nèi)存泄露指對象在不需要使用它時仍然存在,導(dǎo)致占用的內(nèi)存不能使用或回收
未使用 var 聲明的全局變量
閉包函數(shù)(Closures)
循環(huán)引用(兩個對象相互引用)
控制臺日志(console.log)
移除存在綁定事件的DOM元素(IE)
setTimeout?的第一個參數(shù)使用字符串而非函數(shù)的話糯俗,會引發(fā)內(nèi)存泄漏
垃圾回收器定期掃描對象尿褪,并計算引用了每個對象的其他對象的數(shù)量。如果一個對象的引用數(shù)量為 0(沒有其他對象引用過該對象)得湘,或?qū)υ搶ο蟮奈┮灰檬茄h(huán)的杖玲,那么該對象的內(nèi)存即可回收
4 說說你對AMD和Commonjs的理解
CommonJS是服務(wù)器端模塊的規(guī)范,Node.js采用了這個規(guī)范淘正。CommonJS規(guī)范加載模塊是同步的摆马,也就是說臼闻,只有加載完成,才能執(zhí)行后面的操作囤采。AMD規(guī)范則是非同步加載模塊述呐,允許指定回調(diào)函數(shù)
AMD推薦的風(fēng)格通過返回一個對象做為模塊對象,CommonJS的風(fēng)格通過對module.exports或exports的屬性賦值來達(dá)到暴露模塊對象的目的
5 常見web安全及防護(hù)原理
sql注入原理
就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串蕉毯,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令
總的來說有以下幾點
永遠(yuǎn)不要信任用戶的輸入乓搬,要對用戶的輸入進(jìn)行校驗,可以通過正則表達(dá)式代虾,或限制長度进肯,對單引號和雙"-"進(jìn)行轉(zhuǎn)換等
永遠(yuǎn)不要使用動態(tài)拼裝SQL,可以使用參數(shù)化的SQL或者直接使用存儲過程進(jìn)行數(shù)據(jù)查詢存取
永遠(yuǎn)不要使用管理員權(quán)限的數(shù)據(jù)庫連接棉磨,為每個應(yīng)用使用單獨的權(quán)限有限的數(shù)據(jù)庫連接
不要把機密信息明文存放江掩,請加密或者h(yuǎn)ash掉密碼和敏感的信息
XSS原理及防范
Xss(cross-site scripting)攻擊指的是攻擊者往Web頁面里插入惡意html標(biāo)簽或者javascript代碼。比如:攻擊者在論壇中放一個看似安全的鏈接乘瓤,騙取用戶點擊后环形,竊取cookie中的用戶私密信息;或者攻擊者在論壇中加一個惡意表單衙傀,當(dāng)用戶提交表單的時候抬吟,卻把信息傳送到攻擊者的服務(wù)器中,而不是用戶原本以為的信任站點
XSS防范方法
首先代碼里對用戶輸入的地方和變量都需要仔細(xì)檢查長度和對”<”,”>”,”;”,”’”等字符做過濾差油;其次任何內(nèi)容寫到頁面之前都必須加以encode拗军,避免不小心把html tag?弄出來。這一個層面做好蓄喇,至少可以堵住超過一半的XSS 攻擊
XSS與CSRF有什么區(qū)別嗎发侵?
XSS是獲取信息,不需要提前知道其他用戶頁面的代碼和數(shù)據(jù)包妆偏。CSRF是代替用戶完成指定的動作刃鳄,需要知道其他用戶頁面的代碼和數(shù)據(jù)包。要完成一次CSRF攻擊钱骂,受害者必須依次完成兩個步驟
登錄受信任網(wǎng)站A叔锐,并在本地生成Cookie
在不登出A的情況下,訪問危險網(wǎng)站B
CSRF的防御
服務(wù)端的CSRF方式方法很多樣见秽,但總的思想都是一致的愉烙,就是在客戶端頁面增加偽隨機數(shù)
通過驗證碼的方法
6 用過哪些設(shè)計模式?
工廠模式:
工廠模式解決了重復(fù)實例化的問題解取,但還有一個問題,那就是識別問題
主要好處就是可以消除對象間的耦合步责,通過使用工程方法而不是new關(guān)鍵字
構(gòu)造函數(shù)模式:
使用構(gòu)造函數(shù)的方法,即解決了重復(fù)實例化的問題,又解決了對象識別的問題蔓肯,該模式與工廠模式的不同之處在于
直接將屬性和方法賦值給?this對象;
7 offsetWidth/offsetHeight,clientWidth/clientHeight與scrollWidth/scrollHeight的區(qū)別
offsetWidth/offsetHeight返回值包含content + padding + border遂鹊,效果與e.getBoundingClientRect()相同
clientWidth/clientHeight返回值只包含content + padding,如果有滾動條蔗包,也不包含滾動條
scrollWidth/scrollHeight返回值包含content + padding + 溢出內(nèi)容的尺寸
8 javascript有哪些方法定義對象
對象字面量:?var obj = {};
構(gòu)造函數(shù):?var obj = new Object();
Object.create():?var obj = Object.create(Object.prototype);
9 你覺得jQuery源碼有哪些寫的好的地方
jquery源碼封裝在一個匿名函數(shù)的自執(zhí)行環(huán)境中秉扑,有助于防止變量的全局污染,然后通過傳入window對象參數(shù)调限,可以使window對象作為局部變量使用舟陆,好處是當(dāng)jquery中訪問window對象的時候,就不用將作用域鏈退回到頂層作用域了旧噪,從而可以更快的訪問window對象吨娜。同樣脓匿,傳入undefined參數(shù)淘钟,可以縮短查找undefined時的作用域鏈
jquery將一些原型屬性和方法封裝在了jquery.prototype中,為了縮短名稱陪毡,又賦值給了jquery.fn米母,這是很形象的寫法
有一些數(shù)組或?qū)ο蟮姆椒ń?jīng)常能使用到,jQuery將其保存為局部變量以提高訪問速度
jquery實現(xiàn)的鏈?zhǔn)秸{(diào)用可以節(jié)約代碼毡琉,所返回的都是同一個對象铁瞒,可以提高代碼效率
10 Node的應(yīng)用場景
特點:
1、它是一個Javascript運行環(huán)境
2桅滋、依賴于Chrome V8引擎進(jìn)行代碼解釋
3慧耍、事件驅(qū)動
4、非阻塞I/O
5丐谋、單進(jìn)程芍碧,單線程
優(yōu)點:
高并發(fā)(最重要的優(yōu)點)
缺點:
1、只支持單核CPU号俐,不能充分利用CPU
2泌豆、可靠性低,一旦代碼某個環(huán)節(jié)崩潰吏饿,整個系統(tǒng)都崩潰
11 說幾條寫JavaScript的基本規(guī)范
不要在同一行聲明多個變量
請使用===/!==來比較true/false或者數(shù)值
使用對象字面量替代new Array這種形式
不要使用全局函數(shù)
Switch語句必須帶有default分支
If語句必須使用大括號
for-in循環(huán)中的變量 應(yīng)該使用var關(guān)鍵字明確限定作用域踪危,從而避免作用域污
12 js延遲加載的方式有哪些
設(shè)置<script>屬性?defer="defer"?(腳本將在頁面完成解析時執(zhí)行)
動態(tài)創(chuàng)建?script DOM:document.createElement('script');
XmlHttpRequest?腳本注入
延遲加載工具?LazyLoad
13 defer和async
defer并行加載js文件,會按照頁面上script標(biāo)簽的順序執(zhí)行
async并行加載js文件猪落,下載完成立即執(zhí)行贞远,不會按照頁面上script標(biāo)簽的順序執(zhí)行
14 說說嚴(yán)格模式的限制
變量必須聲明后再使用
函數(shù)的參數(shù)不能有同名屬性,否則報錯
不能使用with語句
不能對只讀屬性賦值笨忌,否則報錯
不能使用前綴0表示八進(jìn)制數(shù)蓝仲,否則報錯
不能刪除不可刪除的屬性,否則報錯
不能刪除變量delete prop,會報錯杂曲,只能刪除屬性delete global[prop]
eval不會在它的外層作用域引入變量
eval和arguments不能被重新賦值
arguments不會自動反映函數(shù)參數(shù)的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局對象
不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
增加了保留字(比如protected庶艾、static和interface)
15 attribute和property的區(qū)別是什么
attribute是dom元素在文檔中作為html標(biāo)簽擁有的屬性;
property就是dom元素在js中作為對象擁有的屬性擎勘。
對于html的標(biāo)準(zhǔn)屬性來說咱揍,attribute和property是同步的,是會自動更新的
但是對于自定義的屬性來說棚饵,他們是不同步的
16 談?wù)勀銓S6的理解
新增模板字符串(為JavaScript提供了簡單的字符串插值功能)
箭頭函數(shù)
for-of(用來遍歷數(shù)據(jù)—例如數(shù)組中的值煤裙。)
arguments對象可被不定參數(shù)和默認(rèn)參數(shù)完美代替。
ES6將promise對象納入規(guī)范噪漾,提供了原生的Promise對象硼砰。
增加了let和const命令,用來聲明變量欣硼。
增加了塊級作用域题翰。
let命令實際上就增加了塊級作用域。
還有就是引入module模塊的概念诈胜。
17 異步編程的實現(xiàn)方式
回調(diào)函數(shù)
優(yōu)點:簡單豹障、容易理解
缺點:不利于維護(hù),代碼耦合高
事件監(jiān)聽(采用時間驅(qū)動模式焦匈,取決于某個事件是否發(fā)生):
優(yōu)點:容易理解血公,可以綁定多個事件,每個事件可以指定多個回調(diào)函數(shù)
缺點:事件驅(qū)動型缓熟,流程不夠清晰
發(fā)布/訂閱(觀察者模式)
類似于事件監(jiān)聽累魔,但是可以通過‘消息中心’,了解現(xiàn)在有多少發(fā)布者够滑,多少訂閱者
Promise對象
優(yōu)點:可以利用then方法垦写,進(jìn)行鏈?zhǔn)綄懛ǎ豢梢詴鴮戝e誤時的回調(diào)函數(shù)版述;
缺點:編寫和理解梯澜,相對比較難
Generator函數(shù)
優(yōu)點:函數(shù)體內(nèi)外的數(shù)據(jù)交換、錯誤處理機制
缺點:流程管理不方便
async函數(shù)
優(yōu)點:內(nèi)置執(zhí)行器渴析、更好的語義晚伙、更廣的適用性、返回的是Promise俭茧、結(jié)構(gòu)清晰咆疗。
缺點:錯誤處理機制
18 項目做過哪些性能優(yōu)化?
減少?HTTP?請求數(shù)
減少?DNS?查詢
使用?CDN
避免重定向
圖片懶加載
減少?DOM?元素數(shù)量
減少DOM?操作
使用外部?JavaScript?和?CSS
壓縮?JavaScript?母债、?CSS?午磁、字體尝抖、圖片等
優(yōu)化?CSS Sprite
使用?iconfont
字體裁剪
多域名分發(fā)劃分內(nèi)容到不同域名
盡量減少?iframe?使用
避免圖片?src?為空
把樣式表放在link?中
把JavaScript放在頁面底部
19 瀏覽器緩存
瀏覽器緩存分為強緩存和協(xié)商緩存。當(dāng)客戶端請求某個資源時迅皇,獲取緩存的流程如下
先根據(jù)這個資源的一些?http header?判斷它是否命中強緩存昧辽,如果命中,則直接從本地獲取緩存資源登颓,不會發(fā)請求到服務(wù)器搅荞;
當(dāng)強緩存沒有命中時,客戶端會發(fā)送請求到服務(wù)器框咙,服務(wù)器通過另一些request header驗證這個資源是否命中協(xié)商緩存咕痛,稱為http再驗證,如果命中喇嘱,服務(wù)器將請求返回茉贡,但不返回資源,而是告訴客戶端直接從緩存中獲取者铜,客戶端收到返回后就會從緩存中獲取資源腔丧;
強緩存和協(xié)商緩存共同之處在于,如果命中緩存王暗,服務(wù)器都不會返回資源悔据; 區(qū)別是庄敛,強緩存不對發(fā)送請求到服務(wù)器俗壹,但協(xié)商緩存會。
當(dāng)協(xié)商緩存也沒命中時藻烤,服務(wù)器就會將資源發(fā)送回客戶端绷雏。
當(dāng)?ctrl+f5?強制刷新網(wǎng)頁時,直接從服務(wù)器加載怖亭,跳過強緩存和協(xié)商緩存涎显;
當(dāng)?f5刷新網(wǎng)頁時,跳過強緩存兴猩,但是會檢查協(xié)商緩存期吓;
強緩存
Expires(該字段是?http1.0?時的規(guī)范,值為一個絕對時間的?GMT?格式的時間字符串倾芝,代表緩存資源的過期時間)
Cache-Control:max-age(該字段是?http1.1的規(guī)范讨勤,強緩存利用其?max-age?值來判斷緩存資源的最大生命周期,它的值單位為秒)
協(xié)商緩存
Last-Modified(值為資源最后更新時間晨另,隨服務(wù)器response返回)
If-Modified-Since(通過比較兩個時間來判斷資源在兩次請求期間是否有過修改潭千,如果沒有修改,則命中協(xié)商緩存)
ETag(表示資源內(nèi)容的唯一標(biāo)識借尿,隨服務(wù)器response返回)
If-None-Match(服務(wù)器通過比較請求頭部的If-None-Match與當(dāng)前資源的ETag是否一致來判斷資源是否在兩次請求之間有過修改刨晴,如果沒有修改屉来,則命中協(xié)商緩存)
20 談?wù)勛兞刻嵘?br>
當(dāng)執(zhí)行 JS 代碼時,會生成執(zhí)行環(huán)境狈癞,只要代碼不是寫在函數(shù)中的茄靠,就是在全局執(zhí)行環(huán)境中,函數(shù)中的代碼會產(chǎn)生函數(shù)執(zhí)行環(huán)境蝶桶,只此兩種執(zhí)行環(huán)境
變量提升
這是因為函數(shù)和變量提升的原因嘹黔。通常提升的解釋是說將聲明的代碼移動到了頂部,這其實沒有什么錯誤莫瞬,便于大家理解儡蔓。但是更準(zhǔn)確的解釋應(yīng)該是:在生成執(zhí)行環(huán)境時,會有兩個階段疼邀。第一個階段是創(chuàng)建的階段喂江,JS 解釋器會找出需要提升的變量和函數(shù),并且給他們提前在內(nèi)存中開辟好空間旁振,函數(shù)的話會將整個函數(shù)存入內(nèi)存中获询,變量只聲明并且賦值為?undefined,所以在第二個階段拐袜,也就是代碼執(zhí)行階段吉嚣,我們可以直接提前使用
在提升的過程中,相同的函數(shù)會覆蓋上一個函數(shù)蹬铺,并且函數(shù)優(yōu)先于變量提升
21 什么是單線程尝哆,和異步的關(guān)系
單線程 - 只有一個線程,只能做一件事
原因 - 避免?DOM?渲染的沖突
瀏覽器需要渲染?DOM
JS?可以修改?DOM?結(jié)構(gòu)
JS?執(zhí)行的時候甜攀,瀏覽器?DOM?渲染會暫停
兩段 JS 也不能同時執(zhí)行(都修改?DOM?就沖突了)
webworker?支持多線程秋泄,但是不能訪問?DOM
解決方案 - 異步
22 JavaScript 對象生命周期的理解
當(dāng)創(chuàng)建一個對象時,JavaScript?會自動為該對象分配適當(dāng)?shù)膬?nèi)存
垃圾回收器定期掃描對象规阀,并計算引用了該對象的其他對象的數(shù)量
如果被引用數(shù)量為?0恒序,或惟一引用是循環(huán)的,那么該對象的內(nèi)存即可回收
23 說說從輸入URL到看到頁面發(fā)生的全過程谁撼,越詳細(xì)越好
首先瀏覽器主進(jìn)程接管歧胁,開了一個下載線程。
然后進(jìn)行HTTP請求(DNS查詢厉碟、IP尋址等等)喊巍,中間會有三次捂手,等待響應(yīng)墨榄,開始下載響應(yīng)報文玄糟。
將下載完的內(nèi)容轉(zhuǎn)交給Renderer進(jìn)程管理。
Renderer進(jìn)程開始解析css rule tree和dom tree袄秩,這兩個過程是并行的阵翎,所以一般我會把link標(biāo)簽放在頁面頂部逢并。
解析繪制過程中,當(dāng)瀏覽器遇到link標(biāo)簽或者script郭卫、img等標(biāo)簽砍聊,瀏覽器會去下載這些內(nèi)容,遇到時候緩存的使用緩存贰军,不適用緩存的重新下載資源玻蝌。
css rule tree和dom tree生成完了之后,開始合成render tree词疼,這個時候瀏覽器會進(jìn)行l(wèi)ayout俯树,開始計算每一個節(jié)點的位置,然后進(jìn)行繪制贰盗。
繪制結(jié)束后许饿,關(guān)閉TCP連接,過程有四次揮手
24 說一下瀏覽器的緩存機制
瀏覽器緩存機制有兩種舵盈,一種為強緩存陋率,一種為協(xié)商緩存
對于強緩存,瀏覽器在第一次請求的時候秽晚,會直接下載資源瓦糟,然后緩存在本地,第二次請求的時候赴蝇,直接使用緩存菩浙。
對于協(xié)商緩存,第一次請求緩存且保存緩存標(biāo)識與時間扯再,重復(fù)請求向服務(wù)器發(fā)送緩存標(biāo)識和最后緩存時間芍耘,服務(wù)端進(jìn)行校驗,如果失效則使用緩存
協(xié)商緩存相關(guān)設(shè)置
Exprires:服務(wù)端的響應(yīng)頭熄阻,第一次請求的時候,告訴客戶端倔约,該資源什么時候會過期秃殉。Exprires的缺陷是必須保證服務(wù)端時間和客戶端時間嚴(yán)格同步。
Cache-control:max-age:表示該資源多少時間后過期浸剩,解決了客戶端和服務(wù)端時間必須同步的問題钾军,
If-None-Match/ETag:緩存標(biāo)識,對比緩存時使用它來標(biāo)識一個緩存绢要,第一次請求的時候吏恭,服務(wù)端會返回該標(biāo)識給客戶端,客戶端在第二次請求的時候會帶上該標(biāo)識與服務(wù)端進(jìn)行對比并返回If-None-Match標(biāo)識是否表示匹配重罪。
Last-modified/If-Modified-Since:第一次請求的時候服務(wù)端返回Last-modified表明請求的資源上次的修改時間樱哼,第二次請求的時候客戶端帶上請求頭If-Modified-Since哀九,表示資源上次的修改時間,服務(wù)端拿到這兩個字段進(jìn)行對比
25 ajax搅幅、axios阅束、fetch區(qū)別
jQuery ajax
$.ajax({type:'POST',url:url,data:data,dataType:dataType,success:function(){},error:function(){}});
優(yōu)缺點:
本身是針對MVC的編程,不符合現(xiàn)在前端MVVM的浪潮
基于原生的XHR開發(fā),XHR本身的架構(gòu)不清晰茄唐,已經(jīng)有了fetch的替代方案
JQuery整個項目太大息裸,單純使用ajax卻要引入整個JQuery非常的不合理(采取個性化打包的方案又不能享受CDN服務(wù))
axios
axios({method:'post',url:'/user/12345',data:{firstName:'Fred',lastName:'Flintstone'}}).then(function(response){console.log(response);}).catch(function(error){console.log(error);});
優(yōu)缺點:
從瀏覽器中創(chuàng)建?XMLHttpRequest
從?node.js?發(fā)出?http?請求
支持?Promise API
攔截請求和響應(yīng)
轉(zhuǎn)換請求和響應(yīng)數(shù)據(jù)
取消請求
自動轉(zhuǎn)換JSON數(shù)據(jù)
客戶端支持防止CSRF/XSRF
fetch
try{letresponse=awaitfetch(url);letdata=response.json();console.log(data);}catch(e){console.log("Oops, error",e);}
優(yōu)缺點:
fetcht只對網(wǎng)絡(luò)請求報錯,對400沪编,500都當(dāng)做成功的請求呼盆,需要封裝去處理
fetch默認(rèn)不會帶cookie,需要添加配置項
fetch不支持abort蚁廓,不支持超時控制宿亡,使用setTimeout及Promise.reject的實現(xiàn)的超時控制并不能阻止請求過程繼續(xù)在后臺運行,造成了量的浪費
fetch沒有辦法原生監(jiān)測請求的進(jìn)度纳令,而XHR可以
26 說幾條寫JavaScript的基本規(guī)范
代碼縮進(jìn)挽荠,建議使用“四個空格”縮進(jìn)
代碼段使用花括號{}包裹
語句結(jié)束使用分號;
變量和函數(shù)在使用前進(jìn)行聲明
以大寫字母開頭命名構(gòu)造函數(shù),全大寫命名常量
規(guī)范定義JSON對象平绩,補全雙引號
用{}和[]聲明對象和數(shù)組
27 如何編寫高性能的JavaScript
遵循嚴(yán)格模式:"use strict";
將js腳本放在頁面底部圈匆,加快渲染頁面
將js腳本將腳本成組打包,減少請求
使用非阻塞方式下載js腳本
盡量使用局部變量來保存全局變量
盡量減少使用閉包
使用?window?對象屬性方法時捏雌,省略?window
盡量減少對象成員嵌套
緩存?DOM?節(jié)點的訪問
通過避免使用?eval()?和?Function()?構(gòu)造器
給?setTimeout()?和?setInterval()?傳遞函數(shù)而不是字符串作為參數(shù)
盡量使用直接量創(chuàng)建對象和數(shù)組
最小化重繪(repaint)和回流(reflow)
28 script 的位置是否會影響首屏顯示時間
在解析?HTML?生成?DOM?過程中跃赚,js?文件的下載是并行的,不需要?DOM?處理到?script?節(jié)點性湿。因此纬傲,script的位置不影響首屏顯示的開始時間。
瀏覽器解析?HTML?是自上而下的線性過程肤频,script作為?HTML?的一部分同樣遵循這個原則
因此叹括,script?會延遲?DomContentLoad,只顯示其上部分首屏內(nèi)容宵荒,從而影響首屏顯示的完成時間
29 解釋JavaScript中的作用域與變量聲明提升
JavaScript作用域:
在Java汁雷、C等語言中,作用域為for語句报咳、if語句或{}內(nèi)的一塊區(qū)域侠讯,稱為作用域;
而在?JavaScript?中暑刃,作用域為function(){}內(nèi)的區(qū)域厢漩,稱為函數(shù)作用域。
JavaScript變量聲明提升:
在JavaScript中岩臣,函數(shù)聲明與變量聲明經(jīng)常被JavaScript引擎隱式地提升到當(dāng)前作用域的頂部溜嗜。
聲明語句中的賦值部分并不會被提升宵膨,只有名稱被提升
函數(shù)聲明的優(yōu)先級高于變量,如果變量名跟函數(shù)名相同且未賦值粱胜,則函數(shù)聲明會覆蓋變量聲明
如果函數(shù)有多個同名參數(shù)柄驻,那么最后一個參數(shù)(即使沒有定義)會覆蓋前面的同名參數(shù)
30 css定位
1 相對定位 relative
相對定位是元素在移動位置的時候,是相對于它原來的位置來說的(自戀型)
相對定位的特點:(務(wù)必記妆貉埂)
它是相對于自己原來的位置來移動的(移動位置的時候參照點是自己原來的位置)鸿脓。
原來在標(biāo)準(zhǔn)流的位置繼續(xù)占有,后面的盒子仍然以標(biāo)準(zhǔn)流的方式對待它涯曲。
因此野哭,相對定位并沒有脫標(biāo)。它最典型的應(yīng)用是給絕對定位當(dāng)?shù)幕眉2η!?/p>
2 絕對定位 absolute
絕對定位是元素在移動位置的時候绰沥,是相對于它祖先元素來說的(拼爹型)篱蝇。
絕對定位的特點:(務(wù)必記住)
如果沒有祖先元素(父元素)或者祖先元素沒有定位徽曲,則以瀏覽器為準(zhǔn)定位(Document 文檔)零截。
如果祖先元素有定位(相對、絕對秃臣、固定定位)涧衙,則以最近一級的有定位祖先元素為參考點移動位置。
絕對定位不再占有原先的位置奥此。(脫標(biāo))
所以絕對定位是脫離標(biāo)準(zhǔn)流的弧哎。
3 固定定位?fixed
生成絕對定位的元素,相對于瀏覽器窗口進(jìn)行定位稚虎。只需設(shè)置它相對于各個方向的偏移值撤嫩,就可以將該元素固定在頁面固定的位置,通常用來顯示一些提示信息祥绞,脫離文檔流非洲;
31 介紹事件“捕獲”和“冒泡”執(zhí)行順序和事件的執(zhí)行次數(shù)
按照W3C標(biāo)準(zhǔn)的事件:首是進(jìn)入捕獲階段,直到達(dá)到目標(biāo)元素蜕径,再進(jìn)入冒泡階段
事件執(zhí)行次數(shù)(DOM2-addEventListener):元素上綁定事件的個數(shù)
注意1:前提是事件被確實觸發(fā)
注意2:事件綁定幾次就算幾個事件,即使類型和功能完全一樣也不會“覆蓋”
事件執(zhí)行順序:判斷的關(guān)鍵是否目標(biāo)元素
非目標(biāo)元素:根據(jù)W3C的標(biāo)準(zhǔn)執(zhí)行:捕獲->目標(biāo)元素->冒泡(不依據(jù)事件綁定順序)
目標(biāo)元素:依據(jù)事件綁定順序:先綁定的事件先執(zhí)行(不依據(jù)捕獲冒泡標(biāo)準(zhǔn))
最終順序:父元素捕獲->目標(biāo)元素事件1->目標(biāo)元素事件2->子元素捕獲->子元素冒泡->父元素冒泡
注意:子元素事件執(zhí)行前提 事件確實“落”到子元素布局區(qū)域上败京,而不是簡單的具有嵌套關(guān)系
在一個DOM上同時綁定兩個點擊事件:一個用捕獲兜喻,一個用冒泡。事件會執(zhí)行幾次赡麦,先執(zhí)行冒泡還是捕獲朴皆?
該DOM上的事件如果被觸發(fā)帕识,會執(zhí)行兩次(執(zhí)行次數(shù)等于綁定次數(shù))
如果該DOM是目標(biāo)元素,則按事件綁定順序執(zhí)行遂铡,不區(qū)分冒泡/捕獲
如果該DOM是處于事件流中的非目標(biāo)元素肮疗,則先執(zhí)行捕獲,后執(zhí)行冒泡
事件的代理/委托
事件委托是指將事件綁定目標(biāo)元素的到父元素上扒接,利用冒泡機制觸發(fā)該事件
優(yōu)點:
可以減少事件注冊伪货,節(jié)省大量內(nèi)存占用
可以將事件應(yīng)用于動態(tài)添加的子元素上
缺點: 使用不當(dāng)會造成事件在不應(yīng)該觸發(fā)時觸發(fā)
32 Javascript垃圾回收方法
標(biāo)記清除(mark and sweep)
這是JavaScript最常見的垃圾回收方式,當(dāng)變量進(jìn)入執(zhí)行環(huán)境的時候钾怔,比如函數(shù)中聲明一個變量碱呼,垃圾回收器將其標(biāo)記為“進(jìn)入環(huán)境”,當(dāng)變量離開環(huán)境的時候(函數(shù)執(zhí)行結(jié)束)將其標(biāo)記為“離開環(huán)境”
垃圾回收器會在運行的時候給存儲在內(nèi)存中的所有變量加上標(biāo)記宗侦,然后去掉環(huán)境中的變量以及被環(huán)境中變量所引用的變量(閉包)愚臀,在這些完成之后仍存在標(biāo)記的就是要刪除的變量了
引用計數(shù)(reference counting)
在低版本IE中經(jīng)常會出現(xiàn)內(nèi)存泄露,很多時候就是因為其采用引用計數(shù)方式進(jìn)行垃圾回收矾利。引用計數(shù)的策略是跟蹤記錄每個值被使用的次數(shù)姑裂,當(dāng)聲明了一個 變量并將一個引用類型賦值給該變量的時候這個值的引用次數(shù)就加1,如果該變量的值變成了另外一個男旗,則這個值得引用次數(shù)減1舶斧,當(dāng)這個值的引用次數(shù)變?yōu)?的時 候,說明沒有變量在使用剑肯,這個值沒法被訪問了捧毛,因此可以將其占用的空間回收,這樣垃圾回收器會在運行的時候清理掉引用次數(shù)為0的值占用的空間
33 Vue-Router
1让网、hash模式
hash模式是開發(fā)中默認(rèn)的模式呀忧,也稱作錨點,它的URL帶著一個#溃睹,例如:www.abc.com/#/vue而账,它的hash值就是#/vue。
特點:
hash值會出現(xiàn)在URL里面因篇,但是不會出現(xiàn)在HTTP請求中泞辐,對后端沒有影響。所以改變hash值不會重新加載頁面竞滓。
這種模式的瀏覽器支持度很好咐吼,低版本的IE瀏覽器也支持這種模式。
hash路由被稱為是前端路由商佑,已經(jīng)成為SPA(單頁面應(yīng)用)的標(biāo)配锯茄。
原理:
hash模式的主要原理就是onhashchange()事件:
window.onhashchange = function(event){
console.log(event.oldURL, event.newURL);
let hash = location.hash.slice(1);
使用onhashchange()事件的好處就是,在頁面的hash值發(fā)生變化時,無需向后端發(fā)起請求肌幽,window就可以監(jiān)聽事件的改變晚碾,并按規(guī)則加載相應(yīng)的代碼。除此之外喂急,hash值變化對應(yīng)的URL都會被瀏覽器記錄下來格嘁,這樣瀏覽器就能實現(xiàn)頁面的前進(jìn)和后退。雖然是沒有請求后端服務(wù)器廊移,但是頁面的hash值和對應(yīng)的URL關(guān)聯(lián)起來了糕簿。
獲取頁面hash變化的方法:
(1)監(jiān)聽$route的變化:
// 監(jiān)聽,當(dāng)路由發(fā)生變化的時候執(zhí)行
watch: {
? $route: {
? ? handler: function(val, oldVal){
? ? ? console.log(val);
? ? },
? ? // 深度觀察監(jiān)聽
? ? deep: true
? }
},
(2)通過window.location.hash讀取#值:
window.location.hash 的值可讀可寫,讀取來判斷狀態(tài)是否改變画机,寫入時可以在不重載網(wǎng)頁的前提下冶伞,添加一條歷史訪問記錄。
2步氏、history模式
history模式直接指向history對象响禽,它表示當(dāng)前窗口的瀏覽歷史,history對象保存了當(dāng)前窗口訪問過的所有頁面網(wǎng)址荚醒。URL中沒有#芋类,它使用的是傳統(tǒng)的路由分發(fā)模式,即用戶在輸入一個URL時界阁,服務(wù)器會接收這個請求侯繁,并解析這個URL,然后做出相應(yīng)的邏輯處理泡躯。
特點:
當(dāng)使用history模式時贮竟,URL就像這樣:hhh.com/user/id。相比hash模式更加好看较剃。
雖然history模式不需要#咕别。但是,它也有自己的缺點写穴,就是在刷新頁面的時候惰拱,如果沒有相應(yīng)的路由或資源,就會刷出404來啊送。
history api可以分為兩大部分偿短,切換歷史狀態(tài) 和 修改歷史狀態(tài):
修改歷史狀態(tài):
包括了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法,這兩個方法應(yīng)用于瀏覽器的歷史記錄棧馋没,提供了對歷史記錄進(jìn)行修改的功能昔逗。只是當(dāng)他們進(jìn)行修改時,雖然修改了url篷朵,但瀏覽器不會立即向后端發(fā)送請求纤子。如果要做到改變url但又不刷新頁面的效果,就需要前端用上這兩個API款票。
切換歷史狀態(tài):
包括forward()控硼、back()、go()三個方法艾少,對應(yīng)瀏覽器的前進(jìn)卡乾,后退,跳轉(zhuǎn)操作缚够。
配置:
想要設(shè)置成history模式幔妨,就要進(jìn)行以下的配置(后端也要進(jìn)行配置):
const router = new VueRouter({
? mode: 'history',
? routes: [...]
})
3、兩者對比
調(diào)用 history.pushState() 相比于直接修改 hash谍椅,存在以下優(yōu)勢:
pushState() 設(shè)置的新 URL 可以是與當(dāng)前 URL 同源的任意 URL误堡;而 hash 只可修改 # 后面的部分,因此只能設(shè)置與當(dāng)前 URL 同文檔的 URL雏吭。
pushState() 設(shè)置的新 URL 可以與當(dāng)前 URL 一模一樣锁施,這樣也會把記錄添加到棧中;而 hash 設(shè)置的新值必須與原來不一樣才會觸發(fā)動作將記錄添加到棧中杖们。
pushState() 通過 stateObject 參數(shù)可以添加任意類型的數(shù)據(jù)到記錄中悉抵;而 hash 只可添加短字符串。
pushState() 可額外設(shè)置 title 屬性供后續(xù)使用摘完。
hash模式下姥饰,僅hash符號之前的url會被包含在請求中,后端如果沒有做到對路由的全覆蓋孝治,也不會返回404錯誤列粪;history模式下,前端的url必須和實際向后端發(fā)起請求的url一致谈飒,如果沒有對用的路由處理岂座,將返回404錯誤。
4步绸、總結(jié)
hash模式URL上帶有#掺逼,僅 hash 符號之前的內(nèi)容會被包含在請求中,如 www.hhh.com瓤介,因此對于后端來說吕喘,即使沒有做到對路由的全覆蓋,也不會返回 404 錯誤刑桑。
history模式URL上沒有#氯质,前端的 URL 必須和實際向后端發(fā)起請求的 URL 一致,如 www.hhh.com/user/id祠斧。如果后端缺少對 /use/id 的路由處理闻察,將返回 404 錯誤赐写。