一拒贱、第一部分
1.1值類型和引用類型
1.1.1值類型都是變量,通過在棧中進行存儲,值類型在內存中所占的空間新甙摹闸天;a=100,直接給a分配100的值空間斜做;b=a,直接給b也分配一個100的值空間苞氮;因此a=200,直接修改a的值空間即為200陨享;而b的值空間不變還是100
引用類型在內存中所占空間較大葱淳,一般通過棧和堆進行存儲,給a={age:20}抛姑,會在堆中申請一個內存地址赞厕,指向這個對象{age:20},;也就是說定硝,a中存儲的并不是一個對象皿桑,而是一個內存地址1,這個內存地址1蔬啡,指向這個對象诲侮。把b=a,b也就指向這個內存地址1,箱蟆;當b.age=21沟绪,b就把這個內存地址1改成了指向對象{age:21}了;因此此時的內存地址1已經被改成指向對象{age:21}空猜;a.age打印為改變后的對象{age:21}绽慈。
1..1.2 常見值類型
注意:使用const聲明變量時必須賦值,要不然會報錯
1.1.3常見引用類型
注意:函數(shù)也可當做一個特殊的類型
1.2 typeof運算符和深拷貝
1.2.1 typeof運算符
注意:typeof可以判斷所有的值類型
也可以判斷 函數(shù)類型和引用類型
引用類型只能識別到對象‘object’辈毯,具體還得使用其他方法
1.2.2 深拷貝
1.2.2.1 先看下淺拷貝:
//shanghai
也就是說上面的例子是符合引用類型的坝疼,改變了共同指向的內存地址指向的對象
1.2.2.2 深拷貝:不改變原來內存地址指向的對象
先使用typeof判斷obj是null還是(數(shù)組和對象)
如果typeof obj是null不是(數(shù)組和對象),就返回obj谆沃;
如果instanceof 判斷是數(shù)組钝凶,就返回[];否則返回{};
開始for循環(huán)遍歷數(shù)組或者對象的每個值唁影,要先hasOwnProperty過濾掉不是原型上的屬性耕陷,保證key是obj自己本身 的屬性,在對其屬性進行一一深拷貝遞歸調用据沈;
返回所得結果result:
1.3 變量計算
主要涉及到的有:字符串拼接啃炸、==、if語句和邏輯運算
1.3.1 字符串拼接
1.3.2 == 運算符
1.3.3 if語句和邏輯運算
真變量:!!a === true 的變量卓舵;
假變量:!!a ===false 的變量南用;
假變量都有哪些?
邏輯運算符
上面的例子:1.因為10是變量,所以繼續(xù)看后面的裹虫,0 是假變量肿嘲,所以返回0;
2.' '是假變量筑公,繼續(xù)看后面雳窟,'abc'是真變量,返回'abc'匣屡;
改一下:
1.console.log(0&&) ;
//0
因為0是假變量封救,直接返回0
2.console.log('abc' || ' ') ;
//'abc'因為'abc'是真變量,直接返回'abc'
總結:
1.typeof能判斷哪些類型捣作?
答:1.識別所有值類型
2.識別函數(shù)
3.判斷是否是引用類型
2.==何時用誉结?===何時用?
答:除了判斷==null之外券躁,其他一律用===
3.值類型和引用類型的區(qū)別惩坑?
面試中會出題,比如:
其中x1=obj1.x是干擾判斷,值類型賦值也拜,直接分配內存空間以舒;obj2.x=101,引用類型賦值,改變了與obj1共同指向的內存地址指向的對象慢哈,修改為{x:101}
4.手寫深拷貝
答:首先判斷是值類型還是引用類型蔓钟;再注意判斷obj是數(shù)組還是對象;遞歸
第二部分
題目:
1.如何精準判斷一個變量是不是數(shù)組卵贱?
2.手寫一個簡易 的jQuery滥沫,考慮插件和擴展性
3.class的原型本質,怎么理解
知識點
1.class和繼承
2.類型判斷instanceof
3.原型和原型鏈
2.1 class
2.2 繼承
extends艰赞、 super佣谐、擴展或重寫
2.3 類型判斷-instanceof
通過instanceof判斷引用類型肚吏,前者是否是后者class構建出來的方妖;或者說后者class是前者class構建出來的父類。
注意:Object是所有類的父類
2.4 原型
.prototype叫顯式原型
_proto _叫隱式原型
原型關系:
1.每個class都有顯式原型prototype
2.每個實例都有隱式原型_proto _
3.實例的_proto _指向對應class的prototype
基于原型的執(zhí)行規(guī)則:
1.獲取屬性xiaoluo.name或執(zhí)行方法xialuo.sayHi()
2.先在自身屬性和方法上尋找
3.如果找不到則自動去_proto _中查找
2.5 原型鏈
再看instanceof
可以順著xialuo能否對應到class的原型上的顯式原型上罚攀;
比如党觅,xialuo instanceof Studnet可以找到對應的顯式原型Student.prototype蛉鹿;Student instanceof People可以找到對應的顯式原型People.prototype墨状;People instanceof Object可以找到對應的顯式原型Object.prototype;
問題:
1.如何準確判斷一個變量是不是數(shù)組端圈?
答:使用instanceof炫掐,結合原型鏈圖理解
2.手寫一個簡易的j Query魁莉,考慮插件和擴展性
答:
3.class的原型本質,怎么理解?
答:
1.原型和原型鏈的圖示
2.屬性和方法的執(zhí)行規(guī)則
小結:
1.class和繼承旗唁,結合上面手寫jQuery的示例來理解
2.instanceof
3.原型和原型鏈:圖示和執(zhí)行規(guī)則
第三部分
題目:
1.this不同的使用場景
2.手寫bind函數(shù)
3.實際開發(fā)中閉包的應用場景畦浓,舉例
4.場景題:創(chuàng)建10個a標簽,點擊時候彈出對應的序號
知識點
作用域和自由變量检疫、閉包讶请、this
作用域
作用域分為:全局作用域、函數(shù)作用域屎媳、塊級作用域
3.1作用域:
自由變量:一個變量在當前作用域沒有被定義夺溢,但被使用了,那怎么辦烛谊?可以向上級作用域风响,一層一層一次查找,直到找到為止晒来,如果到全局作用域都還沒找到钞诡,則報錯 xx is not defined
3.2 閉包:
作用域應用的特殊情況,有兩種表現(xiàn):1.函數(shù)作為參數(shù)被傳遞2.函數(shù)作為返回值被返回
注:所有自由變量的查找湃崩,是在函數(shù)定義的地方荧降,向上級作用域查找,而不是在執(zhí)行的地方查找
因為fn()執(zhí)行時攒读,執(zhí)行 create函數(shù)朵诫,create函數(shù)里面返回匿名函數(shù)打印a值,a值在匿名函數(shù)中沒有找到薄扁,想上級 create函數(shù)查找a剪返,找到了,a為100邓梅,因此打印a為100
因為執(zhí)行print(fn)時脱盲,執(zhí)行print函數(shù),print函數(shù)里面執(zhí)行fn()日缨,執(zhí)行fn()則執(zhí)行fn函數(shù)钱反,打印a值,a在fn函數(shù)中沒有找到匣距,向上級全局查找面哥,找到了,a為100毅待,則打印a為100
3.3 this
注意:this的取值是在函數(shù)執(zhí)行的時候被調用尚卫,而不是在定義的時候
應用場景:作為普通函數(shù)被調用、使用call 尸红、apply吱涉、bind被刹泄、作為對象方法被調用、在class方法中調用怎爵、箭頭函數(shù)中
因為fn1()執(zhí)行循签,打印的this是去全局的,所以fn1()執(zhí)行打印window疙咸;而執(zhí)行fn1.call(),call里面可以改變this指向县匠,里面?zhèn)魅肓藢ο髙x:100},所以打印的就是這個對象{x:100}撒轮;而執(zhí)行fn2()乞旦,bind里面也可以改變this指向,里面?zhèn)魅肓藢ο髙x:200}题山,就打印這個對象{x:200}兰粉,注意一點,bind有條件:需要返回一個新的函數(shù)fn2顶瞳,執(zhí)行這個新函數(shù)才可以使用玖姑,而call直接調用就可以使用
eg2:
因為sayHi()作為zhangsan的sayHi()方法被執(zhí)行,使以返回這個對象慨菱;而下面的wait()里面有一個setTimeout()執(zhí)行焰络,也就是說執(zhí)行zhangsan.wait()時,如果沒有setTimeout(),就返回的是zhangsan這個對象符喝,有setTimeout()就相當于作為一個普通函數(shù)被執(zhí)行闪彼,而不是作為一個方法被執(zhí)行,是setTimeout本身觸發(fā)的執(zhí)行协饲,而不是zhangsan畏腕,因此,打印的是this是window
eg3:
這個跟上面那個唯一不同的是setTimeout()里面有個箭頭函數(shù)()=>{}茉稠,而箭頭函數(shù)的this是取它的上級作用域的值描馅,因此跟zhangsan.waitAgain()方法跟zhangsan.sayHi()方法一樣,取得是zhangsan這個對象
eg3:
constructor里面的this代表的是創(chuàng)建的實例而线,sayHi()方法里面的this代表就是zhangsan對象
題目解答:
1.this不同的使用場景
答:1铭污、當做普通函數(shù)被調用 2.使用call、apply吞获、bind 3.作為對象方法調用 4.在class的方法中調用 5.箭頭函數(shù)
2.手寫bind函數(shù)
答:
3.實際開發(fā)中閉包的應用場景况凉,舉例
//100
4.場景題:創(chuàng)建10個a標簽谚鄙,點擊時候彈出對應的序號
因為i是全局變量各拷,而
a.addEventListener('click', function(e){
e.preventDefault()
alert(i)
})
事件是當點擊才會觸發(fā)該事件,所以for循環(huán)非趁朴快早已遍歷到10烤黍,因此每當點擊事件發(fā)生前知市,i就是10,因此點擊0-10速蕊,都彈出10
修改:
將i改成局部變量嫂丙,使其在for循環(huán)塊級作用域里面,每次for循環(huán)的時候就會形成一個塊规哲,每次的值都會不一樣
4.異步
題目:
1.同步和異步的區(qū)別是什么跟啤?
2.手寫用Promise加載一張圖片
3.前端使用異步的場景有哪些?
知識點
1.單線程和異步
2.應用場景
3.callback hell 回調地域和Promise
4.1 單線程和異步
-
js是單線程語言唉锌,只能同時做一件事
2.瀏覽器和node.js已支持js啟動進程隅肥,如web worker
3.js和DOM渲染共用一個線程,因為Js可修改DOM結構
4.遇到等待(網絡請求袄简,定時任務)不能卡住腥放,需要異步,回調cakkback函數(shù)
例子1:
異步:
先執(zhí)行同步的100绿语,遇到等待一秒才執(zhí)行的setTimeout函數(shù)秃症,但異步不會阻塞后面300的執(zhí)行,因此先100吕粹,再300种柑,再等待1秒執(zhí)行200
image.png
// 100 300 200
例子2.
同步:會阻塞代碼的執(zhí)行,alert()沒有完成匹耕,后面的就沒法執(zhí)行
image.png
//先100莹规,彈出200警告框,點擊確認之后才會打印300
4.2應用場景
1.網絡請求泌神,如ajax場景
2.定時任務良漱,如setTimeout定時器
4.3回調地域 callback hell
4.3 Promise
問題:
4.4 手寫promise加載圖片示例
eg1:加載一張圖片
eg2:加載多張圖片
4.5異步應用場景
1.網絡請求,如ajax圖片加載
2.定時任務欢际,如setTimeout
先1母市,遇到等待1秒執(zhí)行的setTimeout異步不會阻塞后面代碼,打印3损趋,再遇到等待0秒患久,也就是立即執(zhí)行的的setTimeout異步,但依然是異步浑槽,因此還是執(zhí)行后面的代碼5蒋失,然后再執(zhí)行立即等待的4,然后再是2
小結
1.單線程和異步桐玻,異步和同步的區(qū)別
2.前端異步的應用場景:網絡請求&定時任務
3.Promise解決callback hell嵌套的問題
js基礎總結
內容:
1.變量的類型和計算
2.原型和原型鏈
3.作用域和閉包
4.異步和單線程
題目:
1.typeof能判斷哪些類型
2.何時使用===何時使用==
3.值類型和引用類型的區(qū)別
4.手寫深拷貝
知識點:
1.值類型 VS 引用類型篙挽,堆棧模型,深拷貝
2.typeof運算符
3.類型轉換镊靴,truly和falsely變量
原型和原型鏈題目:
1.如何準確判斷一個變量是不是數(shù)組铣卡?
2.手寫一個簡易 的 jQuery链韭,考慮插件和擴展性
3.class的原型本質,怎么理解
原型和原型鏈-知識點
1.class和繼承煮落,結合手寫jquery的示例來理解
2.instanceof
3.原型和原型鏈:圖示
4.this的不同應用場景敞峭,如何取值?
5.手寫bind函數(shù)
6.實際開發(fā)遇到的閉包問題(0-10對應彈出)
作用域和閉包-知識點
1.作用域和自由變量
2.閉包:兩種常見方式
&自由變量查找規(guī)則
3.this
4.異步同步區(qū)別蝉仇?
5.手寫promise加載圖片
6.前端使用異步場景
異步和單線程-知識點:
1.單線程和異步旋讹,異步和同步的區(qū)別
2.前端異步的應用場景:網絡請求&定時任務
3.promise解決callback hell
第四部分 JS Web API
1.DOM
DOM操作
題目:
1.DOM是那種數(shù)據結構?
2.DOM操作的常用API?
3.attr和property的區(qū)別轿衔?
4.一次性插入多個DOM節(jié)點骗村,考慮性能?
知識點
1.DOM本質
html解析出來的一棵樹
2.DOM節(jié)點操作
先是獲取DOM節(jié)點呀枢,再attribute胚股,property
獲取dom節(jié)點?
1.通過getElementById獲热骨铩琅拌;
2.通過getElementsByTagName獲取摘刑;
3.通過getElementsByClassName獲冉Α;
4.通過querySelectorAll獲燃纤 党晋;
dom節(jié)點的property:
dom節(jié)點的attr:
總結:
property
和attribute
區(qū)別:property
:修改對象屬性,不會體現(xiàn)到html結構中徐块;attribute
:修改html``屬性未玻,會改變
html結構,兩者都有可能引起
DOM重新渲染胡控,建議盡量用
property`
3.DOM結構操作
3.1新增/插入節(jié)點
新增
移動
3.2獲取子元素列表扳剿,獲取父元素
獲取子元素列表:
const div1 = document.getElementById('div1')
const child = div1.childNodes
獲取父元素
const div1 = document.getElementById('div1')
const parent = div1.parentNode
獲取對應文本text節(jié)點:
3.3刪除子元素
通過removeChild
:
div1.removeChild(child[0])
4.DOM性能
4.1DOM操作占用cpu較多,應避免頻繁的DOM操作
4.2對DOM查詢做緩存
4.3 將頻繁操作改為一次性操作
DOM查詢做緩存
//不緩存DOM查詢結果
for(let i=0;i<document.getElementByTagName('p').length;i++){
//每次循環(huán)昼激,都會計算length庇绽,頻繁進行DOM查詢
}
緩存DOM查詢結果
const pList=document.getElementsByTagName('p');
const length=pList.length
for(let i =0;i<length;i++){
//緩存length凡傅,只進行一次DOM查詢
}
將頻繁操作改為一次性操作
const listNode =document.getElementById('list')
//創(chuàng)建一個文檔片段硼莽,此時還沒有插入到DOM書中
const frag = document.createDocumentFragment();
//執(zhí)行插入
for(let x = 0;x < 10; x++){
const li = document.createElement("li");
li.innerHTML ="list item" + x
frag.appendChild(li)
}
//都完成之后终息,再插入到DOM樹中
listNode.appendChild(frag)
總結
1.DOM是那種數(shù)據結構制跟?
答:樹(DOM樹)
2.DOM操作的常用API?
答:DOM節(jié)點操作和DOM結構操作甥雕、attribute和property
3.attr和property的區(qū)別?
答:attribute是修改html結構省撑,會改變HTML結構揪荣;property是修改對象屬性肆捕,不會體現(xiàn)到html結構中;兩者都有可能引起DOM重新渲染
4.一次性插入多個DOM節(jié)點扫倡,考慮性能?
答:通過frag文檔片段,要考慮到先緩存再一起插入
2.BOM
題目:
1.如何識別瀏覽器的類型
2.分析拆解url各個部分
知識點
navigatior和screen
通過navigatior.userAgent
來查看瀏覽器信息
通過screen
查看屏幕信息:
location
location.href
:網址
location.protocol
:協(xié)議
location.host
:域名
location.pathname
:獲取待path
路徑
location.search
:獲取常用參數(shù)
location.hash
:#后面的內容
history
history.back()
:程序后退
'hiotory.forward()':程序前進
3.事件綁定
題目:
1.編寫一個通用事件監(jiān)聽函數(shù)
2.描述事件冒泡的流程
3.無限下拉的圖片列表休涤,如何監(jiān)聽每個圖片的點擊?
知識點:
3.1 事件綁定
const btn=document.getElementById('btn1');
btn.addEventListener('click',event=>{ console.log('clicked')})
event.target:獲取觸發(fā)的元素;
event.preventDefault() :阻止默認行為
3.2事件冒泡
點擊激活吕座,觸發(fā)p1點擊事件寨闹,打印出“激活 取消”
因為p1>div1>body审姓,先是p1事件打印“激活”,再冒泡到body莱找,觸發(fā)body的點擊事件酬姆,打印“取消”
加上阻止冒泡e.stopPropagation()
3.3事件代理
優(yōu)點:代碼簡潔;減少瀏覽器內存占用(子元素較多需要設置監(jiān)聽時奥溺,只需要在父元素上設置一次即可)
注意:有了
event.preventDefault()
阻止默認事件辞色,點擊某個<a href="#">a2</a>就不會跳轉到#頁面
3.4 編寫一個通用的事件監(jiān)聽函數(shù)?注意this指向
描述事件冒泡的流程浮定?
答:
1.基于DOM樹形結構
2.事件會順著觸發(fā)元素向上冒泡3.應用場景:代理
無限下拉圖片列表相满,如何監(jiān)聽每個圖片的點擊?
答:
1.利用事件代理桦卒;
2.用e.target獲取觸發(fā)元素
3.用matches來判斷是否是觸發(fā)元素
4.ajax
題目:
1.手寫一個簡易的ajax
2.跨域的常用實現(xiàn)方式
知識點:
1.XMLHttpRequest
2.狀態(tài)碼
3.跨域:同源策略立美、跨域解決方案
4.1XMLHttpRequest
在ajacx文件夾下的XMLHttpRequest文件夾下新建data文件夾,data文件夾下面再新建test.json方灾;
訪問
http://127.0.0.1:5500/ajax/XMLHttpRequest/data/test.json
實現(xiàn)get請求:
訪問
http://127.0.0.1:5500/ajax/XMLHttpRequest/index.html
那么建蹄,POST請求:效果無法演示,代碼如下:
0-(未初始化)還沒有調用send()方法;
1-(載入)已調用send()方法洞慎,正在發(fā)送請求
2-(載入完成)send()方法執(zhí)行完成针贬,已經接收到全部響應內容
3-(交互)正在解析響應內容
4-(完成)響應內容解析完成,可以在客戶端調用
xhr.staus
2xx-表示成功處理請求拢蛋,如200桦他;
3xx-需要重定向,瀏覽器直接跳轉谆棱,如301 302 304快压;(301永久重定向,302臨時重定向垃瞧,304資源未被改變)
4xx-客戶端請求錯誤蔫劣,如404 403 (404 沒有找到;403沒有訪問權限)
5xx-服務端錯誤(服務器程序有bug)
4.2 跨域
4.2.1什么是跨域个从?
1.ajax請求時脉幢,瀏覽器要求當前網頁和server必須同源(安全)
2.同源:協(xié)議、域名嗦锐、端口嫌松,三者必須一致
比如:
前端 :http://a.com:8080/;
后端:https://b.com/api/xxx;
4.2.2 加載圖片css js可無視同源策略
1.<img src=跨域的圖片地址/>
2.<link href=跨域的css地址/>
3.<script src=跨域的js地址></script>
4.<img /> 可用于統(tǒng)計大點奕污,可使用第三方統(tǒng)計服務
5.<link /><script>可使用CDN,CDN一般都是外域
6.<script>可實現(xiàn)JSONP
注意:所有的跨域萎羔,都必須經過server端允許和配合;未經server端允許就實現(xiàn)跨域碳默,說明瀏覽器有漏洞贾陷,危險信號
4.3JSONP
1.訪問https://taobao.com,服務端一定會返回一個html文件嗎?
答:不一定嘱根,服務端可以任意動態(tài)拼接數(shù)據返回髓废,只要符合html格式要求;同理于<script src="https://taobao.com/getData.js" >
因此该抒,<script>
可繞過跨域限制慌洪,服務端可以任意動態(tài)拼接數(shù)據返回;<script>就可以獲得跨域的數(shù)據,只要服務端愿意返回
<script>標簽加上username=xxx
改變callback函數(shù)
jQuery實現(xiàn)jsonp
CORS-服務端設置http-header
解答:
1.手寫ajax柔逼?
答:
2.jQuery完整版ajax
補充
1.fetch
[https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch](https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch)
2.axios
執(zhí)行get請求:
執(zhí)行post請求:
執(zhí)行多個請求:
axios API:
5.存儲
題目:
描述cookie蒋譬、localStorage、sessionStorsge區(qū)別愉适?
知識點:
cookie
本身用于瀏覽器和server通訊犯助,被“借用”到本地存儲來维咸,可用document.cookie="xxxx"
來修改剂买。
缺點:存儲大小惠爽,最大4kb;http請求時需要發(fā)送到服務端瞬哼,增加請求數(shù)據量婚肆;只能用document.cookie="xxxx"
來修改,太過簡陋
localStorage和sessionStorage
兩個都是HTML5專門為存儲而設計坐慰,最大可存5M较性;API簡單易用:setItem和getItem;不會隨著http請求被發(fā)送出去
localStorage和sessionStorage的區(qū)別结胀?
1.localStorage數(shù)據會永久存儲赞咙,除非代碼或手動刪除
2.sessionStorage數(shù)據只存在于當前會話,瀏覽器關閉則清空
3.一般用localStorage會更多一些
描述cookie糟港、localStorage攀操、sessionStorsge區(qū)別?
答:
1.容量:cookie是4kb容量秸抚,localStorage和sessionStorsge是5M容量
2.api易用性:cookie用
document.cookie="xxxx"
來修改速和,太過簡陋;localStorage和sessionStorsge使用setItem和getItem3.是否跟隨http請求發(fā)送出去:localStorage和sessionStorsge不會隨著http請求被發(fā)送出去剥汤,因此在客戶端(瀏覽區(qū))颠放;而cookie是會隨著HTTP請求被發(fā)送出去,值服務端
4.數(shù)據上的生命周期的不同:
Cookie 一般由服務器生成秀姐,可設置失效時間慈迈,如果在瀏覽器端生成cookie若贮,默認是關閉后失效省有。
localStorage 除非被永久清除,否則永久保存谴麦。
sessionStorage 僅在當前會話會有效蠢沿,關閉頁面或瀏覽器后被清除
第五部分 開發(fā)環(huán)境
1.git
1.1常用git命令:
答:
(1)git add:把文件添加到git;
(2)git checkout xxx:如果發(fā)現(xiàn)修改錯誤匾效,想還原到以前的狀態(tài);
(3)git commit -m "xxx":提交一行記錄舷蟀;
(4)git push origin master:推送到服務端
(5)git pull origin master:從服務端下載
(6)git branch:開分支
(7)git checkout -b xxx/git checkout xxx:切換分支
(8)git merge xxx:合并分支
2.調試工具
3.抓包
是移動端h5頁,查看網絡請求面哼,需要用工具抓包野宜,windows一般用fidder,Mac OS一般用charles魔策。
抓包過程:
手機和電腦連同一個局域網匈子,將手機道里道電腦上,
手機瀏覽網頁闯袒,抓包虎敦;查看網絡請求游岳,網址代理,https
4.webpack
5.linux命令
ls 查看文件夾其徙;clear清除胚迫;ll查看列表
第六部分 運行環(huán)境
1.網頁是怎么加載的?
2.性能優(yōu)化?
3.安全唾那?
題目:
1.從輸入url到渲染出頁面的整個過程
2.window.onload
和DOMContentLoaded
的區(qū)別
知識點
1.加載資源的形式
2.加載資源的過程
3.渲染頁面的過程
6.1.頁面加載和渲染
6.1.1加載資源的形式有哪些
要加載:
(1)html代碼
(2)媒體文件访锻,如圖片、視頻等闹获;
(3)javascript
朗若、css
6.1.2.加載過程
(1)首先DNS解析:域名->IP地址
(2)瀏覽器根據IP地址向服務器發(fā)起http請求
(3)服務器處理http請求,并返回瀏覽器
6.1.3.渲染過程
(1)根據HTML代碼生成DOM Tree
(2)根據CSS代碼生成CSSOM
(3)將DOM Tree和CSSOM整合行程 Render Tree
(4)根據Render Tree渲染頁面
(5)遇到<script>則暫停渲染昌罩,優(yōu)先加載并執(zhí)行JS代碼哭懈,完成再繼續(xù)
(6)直至把Render Tree渲染完成
示例:
根據html生成DOM樹,根據CSS代碼生成CSSOM茎用,再將DOM Tree和CSSOM整合行程 Render Tree進行渲染遣总;因為無css,所以渲染比較快
根據html生成DOM樹轨功,根據CSS代碼生成CSSOM旭斥,再將DOM Tree和CSSOM整合行程 Render Tree進行渲染
思考:為何把css放在head中?
答:避免重復渲染古涧;因為如果放在body里面的最后垂券,前面html解析生成dom樹,無css羡滑,因此不生成cssom菇爪,等整合render樹渲染后又發(fā)現(xiàn)body下面的css,發(fā)起css解析生成cssdom柒昏,再render樹解析凳宙,這樣就重復了render樹解析渲染
3.
加載過程:首先html解析生成dom樹,渲染出
default
;遇到<script>
標簽要暫停渲染职祷,優(yōu)先加載<script>
的js代碼氏涩,將內容改成update by js
;然后再繼續(xù)解析html代碼有梆,渲染p標簽
思考:為何建議把js放到body最后?
答:示例2是為了講解知識點是尖,實際開發(fā)js位置不是很合理,應該把js代碼放到body最后泥耀。因為示例2會導致渲染的時間過長饺汹,先是渲染出dom樹,遇到script優(yōu)先加載js代碼后爆袍,又dom渲染了一遍首繁,這樣渲染的時間過長作郭;應該把js代碼放到body最后,把html渲染完后再執(zhí)行script的渲染弦疮。
加載過程:首先解析html生成dom樹夹攒,渲染出test,遇到img標簽胁塞,這個不像script咏尝,不會阻塞dom渲染,一遍渲染img啸罢,一般繼續(xù)dom渲染编检,可能圖片比較大,渲染時間較長扰才,會先空著允懂,繼續(xù)渲染下面的test,等img渲染完成衩匣,填充即可
6.1.4.window.onload
和DOMContetLoaded
區(qū)別
答:window.addEventListener('load',function (){ })
:頁面的全部資源加載完才會執(zhí)行蕾总,包括圖片、視頻
而document.addEventListener('DOMContentLoaded',function(){ })
:DOM渲染完即可執(zhí)行琅捏,此時圖片生百、視頻可能還沒加載完。
一般監(jiān)聽DOMContetLoaded
,不用等到圖片加載完柄延,加載完dom即可
eg:
圖片較大還沒加載完蚀浆,dom已渲染完成,所有資源渲染完之后然后再是winow loader搜吧;多個圖片的話市俊,會按照實際的圖片加載速度
6.2 性能優(yōu)化
性能優(yōu)化原則:
1.多使用內存、緩存或其他方法
2.減少CPU計算量赎败,減少網絡加載耗時
3.適用于所有編程的性能優(yōu)化-空間換時間
如何入手秕衙?
1.讓加載更快:
1.1減少資源體積:壓縮代碼(比如做webpack時,在生產環(huán)境下打包僵刮,代碼體積會比在開發(fā)環(huán)境打包更小)
1.2 減少訪問次數(shù):合并代碼(比如雪碧圖)鹦牛,SSR
服務端渲染(服務端把頁面以及顯示內容一起渲染搞糕,不用前端通過ajax發(fā)送請求再返回數(shù)據渲染),緩存(比如有10個資源曼追,不用緩存需要訪問10次窍仰,用了緩存訪問一次即可)
1.3使用更快的網絡:CDN
2.讓渲染更快:
2.1 CSS放在head,Js放在body最下面
2.2 盡早開始執(zhí)行Js礼殊,用DOMContentLoaded觸發(fā)
2.3 懶加載(圖片懶加載驹吮,上滑加載更多)
2.4 對DOM查詢進行緩存(DOM操作比較耗費性能针史,需要進行緩存)
2.5 頻繁DOM操作,合并到一起插入DOM結構
2.6 節(jié)流throttle碟狞、防抖debounce
解釋:
1.資源合并
2.緩存
靜態(tài)資源加hash后綴啄枕,根據文件內容計算hash;
文件內容不變族沃,則hash不變频祝,url不變烘嘱;url和文件不變辐怕,則會自動觸發(fā)http緩存機制笙以,返回304
bundle.[contenthash].js
文件變hash變余素,文件不變hash不變。比如上線一個新功能炊昆,代碼中包括老內容和新內容桨吊,只有一個文件是新內容,那么老文件url和文件不變凤巨,會觸發(fā)http緩存機制视乐,返回304;新文件會計算新的hash新的url敢茁,自動下載佑淀。我們希望不變的觸發(fā)緩存,變的重新計算下載
3.CDN
CDN是專門做靜態(tài)文件的服務彰檬,也滿足緩存的304機制
4.SSR
1.服務端渲染:將網頁和數(shù)據一起加載伸刃,一起渲染
2.非SSR(前后端分離):先加載數(shù)據,再渲染數(shù)據
3.早先JSP僧叉、ASP奕枝、PHP都是,現(xiàn)在的vue瓶堕、react SSR
5.懶加載
說明:比如新聞列表,我們希望圖片不是一下子加載完症歇,而是首先顯示第一屏的圖片郎笆,再是隨著向上滑動谭梗,圖片逐漸顯示完框咙。
abc.png是圖片真實地址榴徐,當頁面有10張圖片柄驻,第一屏有5張圖片幅骄,顯示的是體積較小的預覽圖片preview.png郎逃,隨著向上滑動(可由dom節(jié)點距離屏幕頂部top的值判斷)询件,再將圖片真實地址賦值給dom節(jié)點
6.緩存DOM查詢
不緩存dom查詢結果
緩存dom查詢結果
7.多個dom操作一起插入到dom結構
8.盡早開始js執(zhí)行
window.addEventListener('load',function (){ })
:頁面的全部資源加載完才會執(zhí)行缚忧,包括圖片僵控、視頻而
document.addEventListener('DOMContentLoaded',function(){ })
:DOM渲染完即可執(zhí)行痕钢,此時圖片图柏、視頻可能還沒加載完。
6.3 防抖和節(jié)流
6.3.1 防抖debounce
監(jiān)聽一個輸入框時任连,文字變化后觸發(fā)change事件
直接用keyup事件蚤吹,則會頻繁觸發(fā)change事件
防抖:用戶輸入結束或暫停時,才會觸發(fā)change事件
機制原理:設置一個定時器随抠,當定時器為空時裁着,觸發(fā)異步請求再請空,
比如輸入‘12’拱她;開始timer初始化為null二驰,觸發(fā)keyup監(jiān)聽事件,執(zhí)行setTimeout()異步請求,5秒還沒到秉沼,已輸入2桶雀,觸發(fā)監(jiān)聽事件,此時timer是有值的氧猬,timer有值背犯,執(zhí)行
clearTimerout(timer)
,清除了1的定時任務異步操作不打印盅抚,重新設置一個2的定時任務漠魏,等5秒到打印,timer重置null妄均。
那么柱锹,封裝一下:
6.3.2 節(jié)流
拖拽一個元素時,要隨時拿到鈣元素被拖拽的位置丰包;
直接用drag事件禁熏,則會頻繁觸發(fā),很容易導致卡頓
節(jié)流:無論拖拽速度多快邑彪,都會每隔100ms觸發(fā)一次
封裝一下:
6.4 安全
問題:常見的web前端攻擊方式有哪些瞧毙?
6.4.1 安全-xss攻擊
示例:一個博客網站,我發(fā)表了一篇博客,其中嵌入<script>腳本宙彪,腳本內容是獲取cookie矩动,發(fā)送到我的服務器(服務器配合跨域),當發(fā)布了這篇博客释漆,有人查看它悲没,我就可以輕松收割訪問者的cookie
這樣訪問者的信息就可以被獲取到,可以通過跨域ajax等方式傳到對方服務器
那么怎么預防男图?
6.4.2 xss
預防
替換特殊字符示姿,如<
變?yōu)?code>< 把>
變?yōu)?code>>
<script>
變?yōu)?code><script>直接顯示,而不會作為腳本運行逊笆;
前端要替換栈戳,后端也要替換,都做總不會有錯
這樣會作為字符串被解析览露,而不會被運行
6.4.3 XSRF攻擊
示例:小明正在網上購物荧琼,看中了某個商品,商品id是100.付費接口是xxx.com/pay?id=100差牛,但沒有任何驗證命锄;小王是攻擊者,看重另外一個商品偏化,id是200脐恩;那么小王向小明發(fā)送一封電子郵件,標題很吸引人侦讨,比如中獎了驶冒,但郵件正文隱藏著<img src=xxx.com.pay?id=200 />,小明已查看郵件韵卤,就幫小王買了id是200的商品骗污。
XSRF預防?
1.使用post接口
2.增加驗證:比如密碼沈条,短信驗證碼需忿、指紋驗證等。
- 在請求地址中添加takon驗證
CSRF 攻擊之所以能夠成功蜡歹,是因為黑客可以完全偽造用戶的請求屋厘,該請求中所有的用戶驗證信息都是存在于 cookie 中,因此黑客可以在不知道這些驗證信息的情況下直接利用用戶自己的 cookie 來通過安全驗證月而。要抵御 CSRF汗洒,關鍵在于在請求中放入黑客所不能偽造的信息,并且該信息不存在于 cookie 之中父款∫绨可以在 HTTP 請求中以參數(shù)的形式加入一個隨機產生的 token瞻凤,并在服務器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確溯香,則認為可能是 CSRF 攻擊而拒絕該請求鲫构。
這種方法要比檢查 Referer 要安全一些浓恶,token 可以在用戶登陸后產生并放于 session 之中玫坛,然后在每次請求時把 token 從 session 中拿出,與請求中的 token 進行比對包晰。
面試題
1.var 和let const區(qū)別湿镀?
答:
var是es5語法,let伐憾、const是es6語法勉痴,var有變量提升;
var和let是變量树肃,可修改蒸矛;const是常量,不可修改胸嘴;
let const有塊級作用域(外面訪問不到)雏掠,var沒有
2.typeof能判斷哪些類型?
答:
- 值類型:
undefined``number
,string
,boolean
,symbol
- 引用類型:
object
(注意劣像,typeof null === 'object') - function
3.列舉強制類型轉換和隱式類型轉換
答:
強制:parseInt
乡话、parseFloat
、toString
等耳奕;
隱式:if
绑青、邏輯運算、==屋群、+拼接字符串
4.手寫深度比較闸婴,模擬lodash isEqual
答:
5.split()
和join()
的區(qū)別
答:
'1-2-3'.split('-')
//[1,2,3];
[1,2,3].join('-')
//'1-2-3'
6.數(shù)組的pop
、push
芍躏、unshift
邪乍、shift
分別做什么?
答:
功能是什么纸肉?
返回值是什么溺欧?
是否會對原數(shù)組造成影響?
[圖片上傳失敗...(image-8a369d-1583225059539)]
【擴展】數(shù)組的api柏肪,有哪些是純函數(shù)姐刁?
答:純函數(shù):1.不改變原數(shù)組(副作用),2.返回一個數(shù)組
concat:
const arr1 = arr.concat([50,60,70])
map:
const arr2 = arr.map(num =>num*10)
filter:
const arr3 = arr.filter(num =>num >25)
slice:
const arr4 = arr.slice()
非純函數(shù):
psuh烦味、pop shift聂使、 unshift;
forEach;
some every;
reduce;
7.數(shù)組slice和splice區(qū)別
答:
- 功能區(qū)別(slice 切片壁拉,splice剪接)
- 參數(shù)和返回值
-
是否純函數(shù)?
image.png
image.png
8.[10,20,30]map(parseInt)?
答:這里說的很清楚
https://blog.csdn.net/willard_cui/article/details/81504782
當忽略參數(shù) radix , JavaScript 默認數(shù)字的基數(shù)如下:
如果 string 以 "0x" 開頭柏靶,parseInt() 會把 string 的其余部分解析為十六進制的整數(shù)弃理。
如果 string 以 0 開頭,那么 ECMAScript v3 允許 parseInt() 的一個實現(xiàn)把其后的字符解析為八進制或十六進制的數(shù)字屎蜓。
如果 string 以 1 ~ 9 的數(shù)字開頭痘昌,parseInt() 將把它解析為十進制的整數(shù)。
9.ajax請求get和post區(qū)別炬转?
答:1)get一般用于查詢操作辆苔,post一般用于提交操作;
2)get參數(shù)拼接在url上扼劈,post放在請求體內(數(shù)據體積可更大)驻啤;
3)安全性:post易于防止CSRF
10.函數(shù)call和apply的區(qū)別?
答:傳參方式不同:
call是零散的傳參方式荐吵,apply是以數(shù)組的形式
fn.call(this,p1,p2,p3)
;
fn.apply(this,arguments)
;
11.事件代理(委托)是什么骑冗?
答:
12.閉包是什么?有何特性先煎?有何影響贼涩?
答:
1)回顧作用域和自由變量
2) 回顧閉包應用場景:作為參數(shù)被傳入,作為返回值被返回榨婆;
3) 回顧:自由變量的查找磁携,要再函數(shù)定義的地方(不是執(zhí)行的地方)
4)影響:變量會常駐內存,得不到釋放良风。閉包不要亂用
例1:
程序執(zhí)行完
return a=a1+a2+a3;
a3谊迄、a2、a1烟央、a被逐層釋放例2:
閉包统诺,函數(shù)作為返回值:
閉包例子中的 a=100不能被釋放,因為作為返回值了
下面的a =200可以釋放
例3:
閉包疑俭,函數(shù)作為參數(shù):
a=100不能被釋放粮呢,a=200可以被釋放
13.如何阻止事件冒泡和默認行為?
答:阻止事件冒泡:event.stopPropagation()
和阻止默認行為:event.preventDefault()
14.查找钞艇、添加啄寡、刪除、移動DOM節(jié)點的方法哩照?
答:
15.如何減少DOM操作挺物?
1)緩存DOM查詢結果(比如查詢dom的list,可以先把list查出來保存飘弧,不要每次用再去查dom)识藤;
2)多次DOM操作砚著,合并到一次插入(比如文檔片段片段)
16.解釋jsonp
原理,為何不是真正的ajax
痴昧?
答:ajax
是通過XMLHttpRequest
實現(xiàn)稽穆,jsonp
是通過javascript標簽
實現(xiàn);
1)瀏覽器的同源策略(服務端沒有同源策略)和跨域
2)哪些html標簽能繞過跨域?
3)jsonp原理
定義一個全局函數(shù)赶撰,訪問一個js文件舌镶,返回數(shù)據
17.document.load和read的區(qū)別?
答:18.==和===區(qū)別扣囊?
答:
1)==會嘗試類型轉換
2)=== 嚴格相等
3)==使用場景乎折?在==null時,其他都有===
19.函數(shù)聲明和函數(shù)表達式的區(qū)別侵歇?
答:
函數(shù)聲明:function fn(){}
;
函數(shù)表達式:const fn = function(){}
;
函數(shù)聲明會在代碼執(zhí)行前預加載,(相當于變量提升)吓蘑,而函數(shù)表達式不會
函數(shù)聲明:
//30
函數(shù)表達式:
因為是var sum惕虑,存在變量提升,沒有被賦值磨镶,所以是undefined溃蔫;但不是function
20.new Object()和Object.create()的區(qū)別?
答:
首先琳猫,{}等同于new Object(),原型Object.prototype;
其次伟叛,Object.create(null)沒有原型;Object.create({...})可指定原型
21.this場景脐嫂?
//1
//undefined
22.關于作用域和自由變量的場景題统刮?
答:23.判斷字符串以字母開頭,后面字母數(shù)字下劃線账千,長度6-30
答:const reg=/^[a-zA-Z]\w{5,29}$/
小寫英文字母:/^[a-z]+$/
英文字母:/^[a-zA-Z]+$/
日期格式 2019-12-1 (\d表示查找數(shù)字):/^\d{4}-/d{1,2}-\d{1,2}$/
用戶名(\w 元字符用于查找單詞字符,單詞字符包括:a-z侥蒙、A-Z、0-9匀奏,以及下劃線, 包含 _ (下劃線) 字符):/^[a-zA-Z]\w{5,17}$/
簡單的IP地址匹配 127.0.0.1(\d表示查找數(shù)字):/\d+\.\d+\.\d+\.\d+/
24.關于作用域和自由變量的場景題鞭衩?
答:
25.手寫字符串trim保證瀏覽器兼容性
答:
25.獲取多個數(shù)字中的最大值
答:
26.如何用js繼承?
答:
1.class繼承
2.prototype繼承
27.如何捕獲js中的異常娃善?
答:
高風險處:
其他地方:
27.什么是JSON?
答:1.json是一種數(shù)據格式论衍,本質是一段字符串;
2.json格式和js對象結構一致聚磺,對js語言更友好
3.window.JSON是一個全局對象:JSON.stringify(對象轉化成字符串)和JSON.parse(字符串轉化成對象)
//json里面不能用單引號
28.獲取當前頁面url參數(shù)
答:1.傳統(tǒng)方式:查找location.search
2.新api:URLSearchParams
29.將url參數(shù)解析為js對象
答:1.傳統(tǒng)
2.新api:
30.手寫數(shù)組flatern坯台,考慮多層級
答:1.遞歸
2.reduce
3.toString & split
4.join & split
5.es6擴展運算符
[].concat(...[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]
31.數(shù)組去重
答:
1.傳統(tǒng)方式:遍歷元素逐個比較,去重
2.set(無序咧最,不能重復)捂人,效率高
32.手寫深拷貝
注意:Object.assign不是深拷貝御雕,是淺層的
因此滥搭,注意Object.assign是淺拷貝
33.介紹RAF requestAnimationFrame
答:
1.要想動畫流暢疾嗅,更新頻率要60幀/s膀估,即16.67ms更新一次視圖
2.setTimeout要手動控制頻率,而RAF瀏覽器會自動控制
3.后臺標簽或隱藏iframe中束昵,RAF會暫停兼砖,而setTimeout依然執(zhí)行
代碼演示:
1.用setTimeout方法:時間需要自己計算控制
2.用
requestAnimationFrame
方法拆檬,無需自己控制時間,推薦如何性能優(yōu)化啦鸣,從哪幾方面考慮泣矛?
答:1.原則:多使用內存园欣、緩存、減少計算脖旱、減少網絡請求
2.方向:加載頁面介蛉,頁面渲染,頁面操作流暢度