第一章 課程簡介
拿到一個面試題,你第一時間看到的是什么? 考點
又如何看待網(wǎng)上搜出來的永遠(yuǎn)看不完的題海? 以不變應(yīng)萬變
如何對待接下來遇到的面試題? 題目到知識再到題目
第二章 JS基礎(chǔ)知識(上)
變量類型
值類型VS引用類型
引用類型:對象、數(shù)組、函數(shù)
強制類型轉(zhuǎn)換
字符串拼接
==運算符
Eg:
100 == ‘100’// true
0 == ‘’// true
null == undefined //true
if語句
邏輯運算符
問題:JS中使用typeof能得到的那些類型
typeof undefined // undefined
typeof ‘a(chǎn)bc’ //string
typeof 123 //number
typeof true // boolean
typeof {} // object
typeof [] // object
typeof null // object
typeof console.log // function
問題:何時使用===何時使用==?
If(obj.a == null){
//這里相當(dāng)于obj.a === null || obj.a == undefined ,簡寫形式
//這里是jquery源碼中推薦的寫法
}
問題:JS中有哪些內(nèi)置函數(shù) -數(shù)據(jù)封裝對象
Object、Array、Boolean、Number、String、Function、Date、RegExp、Error
問題:JS變量按照存取方式區(qū)分哪些類型?
值類型 引用類型
問題:如何理解JSON
JSON只不過是JS對象而已
JSON.stringify({a:10,b:20})
JSON.parse('{"a":20,"10":20}')
原型和原型鏈
構(gòu)造函數(shù)
構(gòu)造函數(shù) - 擴展
var a = {} - var a = new Object()
var a = [] - var a = new Array()
function Foo(){ ... } - var Foo = new Function( ... )
推薦使用前面的書寫方式,不論從易讀性和性能上看。
使用instance of判斷一個函數(shù)是否是一個變量的構(gòu)造函數(shù)
判斷一個變量是否為“數(shù)組”:變量instance of
原型規(guī)則和示例
1.所有的引用類型(數(shù)組、對象、函數(shù)),都具有對象特性,即可自由擴展屬性(除了“null”之外)。
2.所有的引用類型(數(shù)組、對象、函數(shù)),都具有一個—proto(隱式原型)屬性,屬性值是一個普通的對象。
3.所有的函數(shù),都有一個prototype(顯示原型)屬性,屬性值是一個普通的對象。
4.所有的引用類型(數(shù)組、對象、函數(shù)),proto屬性值指向它的構(gòu)造函數(shù)的“prototype”屬性值。
5.當(dāng)試圖得到一個對象的屬性時,如果這個對象本身沒有這個屬性,那么會去它的的proto(即它的構(gòu)造函數(shù)的prototype)中尋找。
循環(huán)對象自身的屬性
原型鏈
Instance of
用于判斷引用類型屬于哪個構(gòu)造函數(shù)的方法
解題
第三章 JS基礎(chǔ)知識(中)
作用域和閉包
知識點
執(zhí)行上下文
This
作用域
作用域鏈
閉包
執(zhí)行上下文
范圍:一段<script>或者一個函數(shù)
全局:變量定義、函數(shù)聲明 一段<script>
函數(shù):變量定義、函數(shù)聲明、this、arguments 函數(shù)
PS:注意“函數(shù)聲明”和“函數(shù)表達(dá)式”的區(qū)別
This
This要在執(zhí)行時才能確認(rèn)值,定義時無法確認(rèn)
作為構(gòu)造函數(shù)執(zhí)行
作為對象屬性執(zhí)行
作為普通函數(shù)執(zhí)行
Call apply bind
作用域
沒有塊級作用域
只有函數(shù)和全局作用域
作用域鏈
閉包
閉包的使用場景
函數(shù)作為返回值
函數(shù)作為參數(shù)傳遞
實際開發(fā)中閉包的應(yīng)用
1.說下對變量提升的理解
變量定義
函數(shù)聲明
- 說明this幾種不同的使用場景
作為構(gòu)造函數(shù)執(zhí)行
作為對象屬性執(zhí)行
作為普通函數(shù)執(zhí)行
Call apply bind
- 創(chuàng)建10個<a>便簽,點擊的時候彈出來對應(yīng)的序號
var i;
for(i = 0;i < 10;i++){
(function(i){
a = document.createElement('a');
a.innerHTML = i + '<br>';
a.addEventListener('click',function(e){
e.preventDefault();
alert(i);
})
document.body.appendChild(a);
})(i);
}
- 如何理解作用域
自由變量
作用域鏈,即自由變量的查找
閉包的兩個使用場景
第四章 JS基礎(chǔ)知識(下)
異步和單線程
何時需要異步
在可能發(fā)生等待的情況
在等待過程中不能像alert一樣阻塞程序進(jìn)行
因此,所有的“等待的情況”都需要異步
前端使用異步的場景
定時任務(wù):setTimeout,setInverval
網(wǎng)絡(luò)請求:ajax請求,動態(tài)<img>加載
事件綁定
同步和異步的區(qū)別是什么
同步會阻塞代碼執(zhí)行,而異步不會
Alert是同步,setTimeout是異步
日期和math
日期
Math
數(shù)組API
對象API
日期
第五章 JS-Web-API(上)
回顧JS基礎(chǔ)知識
變量類型和計算
原型和原型鏈
閉包和作用域
異步和單線程
其他(如日期、Math、各種常用API)
特點:表面看來并不能用于工作中開發(fā)代碼
內(nèi)置函數(shù):Object Array Boolean String...
內(nèi)置對象:Math JSON
我們連網(wǎng)頁彈出一句hello world都不能實現(xiàn)
JS基礎(chǔ)知識:ECMA 262標(biāo)準(zhǔn)
JS-Web-API:W3C標(biāo)準(zhǔn)
W3C標(biāo)準(zhǔn)中關(guān)于JS的規(guī)定有:
DOM操作
BOM操作
事件綁定
頁面彈框window.alert(123),瀏覽器需要做:
定義一個window全局變量,對象類型
給它定義一個alert屬性,屬性值是個函數(shù)
獲取元素document。getElementById(id),瀏覽器需要:
定義一個document全局變量,對象類型
給它定義一個getElementById的屬性,屬性值是個函數(shù)
但是W3C標(biāo)準(zhǔn)沒有規(guī)定任何JS基礎(chǔ)相關(guān)的東西
不管什么變量類型,原型,作用域和異步
只管定義用于瀏覽器JS操作頁面的API和全局變量
全面考慮,JS內(nèi)置的全局函數(shù)和對象有哪些?
總結(jié)
常說的JS(瀏覽器執(zhí)行的JS)包括兩部分:
JS基礎(chǔ)知識(ECMA262標(biāo)準(zhǔn))
JS-Web-API(W3C標(biāo)準(zhǔn))
DOM操作
Document Object Model
DOM是哪種基本的數(shù)據(jù)結(jié)構(gòu)?
DOM操作的常用API有哪些?
DOM節(jié)點的attr和property有何區(qū)別?
第六章 JS-Web-API(下)
//JS-Web-API
//通用事件綁定
var btn = document.getElementById('btn1');
btn.addEventListener('click',function(event){
console.log('clicked');
}
function bindEvent(elem,type,fn){
elem.addEventListener(type.fn)
}
var a = document.getElementById('link1');
bindEvent(a,'click',function(e){
e.preventDefault(); //阻止默認(rèn)行為
alert('clicked');
})
//關(guān)于IE低版本的兼容性
//IE低版本使用attachEvent綁定事件,和W3C標(biāo)準(zhǔn)不一樣
//IE低版本使用量已經(jīng)非常少,很多網(wǎng)站都早已不支持
//建議對IE低版本的兼容性:了解即可,無需深究
//如果遇到對IE低版本要求苛刻的面試,果斷放棄
//事件冒泡
// <div class="div1">
// <p id='p1'>激活</p>
// <p id='p2'>取消</p>
// <p id='p3'>取消</p>
// <p id='p4'>取消</p>
// </div>
// <div class="div2">
// <p id="p5">取消</p>
// <p id="p6">取消</p>
// </div>
var p1 = document.getElementById('p1');
var body = document.body;
bindEvent(p1,'click',function(e){
e.stopPropagation(); //阻止事件冒泡
alert('激活');
})
bindEvent(body,'click',function(e){
alert('取消');
})
//事件代理
// <div id="div1">
// <a href="#">a1</a>
// <a href="#">a2</a>
// <a href="#">a3</a>
// <a href="#">a4</a>
// </div>
var div1 = document.getElementById('div1');
div1.addEventListener('click',function(e){
var target = e.target;
if (target.nodename === 'A') {
alert(target.innerHTML);
}
})
//完善通用綁定事件的函數(shù)
function bindRvent(elem,type,selector.fn){
if(fn == null){
fn = selector;
selector = null;
}
elem.addEventListener(type,function(e){
var target;
if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target,e);
}else{
fn(e);
}
}
})
}
//使用代理
var div1 = document.getElementById('div1');
bindEvent(div1,"click","a",function(e){
console.log(this.innerHTML);
})
//不使用代理
var a = document.getElementById('a1');
bindEvent(div1,'click',function(e){
console.log(a.innerHTML);
})
代理的好處
1.代碼簡潔
2.減少瀏覽器內(nèi)存占用
簡述事件冒泡流程
1.DOM樹形結(jié)構(gòu)
2.事件冒泡
3.阻止冒泡
冒泡的應(yīng)用
無限下拉加載圖片的頁面,綁定事件
使用代理
Ajax
XMLHttpRequest
狀態(tài)碼
跨域
readyState
0-(未初始化)還沒有調(diào)用send()方法
1-(載入)已調(diào)用send()方法,正在發(fā)生請求
2-(載入完成)send()方法執(zhí)行完成,已經(jīng)接受全部響應(yīng)內(nèi)容
3-(交互)正在解析響應(yīng)內(nèi)容
4-(完成)響應(yīng)內(nèi)容解析完成,可以在客戶端調(diào)用了
status
2xx-表示成功處理請求。如200
3xx-需要重定向,瀏覽器直接跳轉(zhuǎn)
4xx-客戶端請求錯誤,如404
5xx-服務(wù)端錯誤
跨域
JSONP
服務(wù)端設(shè)置http header
什么是跨域
瀏覽器有同源策略,不允許訪問其他域接口
跨域條件:協(xié)議、域名、端口,有一個不同就算跨域
但是有三個便簽允許跨域加載資源
<img src=xxx>
<link href=xxx>
<script src=xxx>
<img>用于打點統(tǒng)計,統(tǒng)計網(wǎng)站可能是其他域
<link><script>可以使用CDN,CDN的也是其他域
<script>可以用于JSONP
跨域注意事項
所有的跨域請求都必須經(jīng)過信息提供方允許
如果未經(jīng)允許即可獲取,那是瀏覽器同源策略出現(xiàn)漏洞
JSONP實現(xiàn)原理
//加載http://coding.m.imooc.com/classindex.html
不一定服務(wù)器真正有一個classindex.html
服務(wù)器可以根據(jù)請求,動態(tài)生成一個文件,返回
同理于<script src="http://coding.m.imooc.com/api.js">
服務(wù)端設(shè)置http header
存儲
請描述一下cookie,sessionStorage和localStorage的區(qū)別?
容量
是否會攜帶到ajax中
API易用性
cookie
本身用于客服端和服務(wù)端通信
但是它本身有本地存儲的功能,于是就被“借用”
使用document.cookie=...獲取和修改即可
cookie用于存儲的缺點
存儲量太小,只有4KB
所有的http請求都帶著,會影響獲取資源的效率
API簡單,需要封裝才能使用document.cookie=...
sessionStorage和localStorage
HTML5專門為存儲而設(shè)計,最大容量5M
APi簡單易用
localStorage.setItem(key.value);localStorage.getItem(key);
IOS safari隱藏模式下
localStorage.setItem會報錯
建議統(tǒng)一使用try-catch封裝
第七章 開發(fā)環(huán)境
關(guān)于開發(fā)環(huán)境
面試官想通過開發(fā)環(huán)境了解面試者的經(jīng)驗
開發(fā)環(huán)境,最能體現(xiàn)工作產(chǎn)出的效率
會以聊天的形式為主,而不是具體的問題
IDE(寫代碼的效率)
Git****(代碼版本管理,多人協(xié)作開發(fā))
JS模塊化
打包工具
上線回滾的流程
IDE(集成開發(fā)環(huán)境)
Webstorm
Sublime
Vscode
Atom
插件 插件 插件?。?!
如果你要走大牛、大咖、逼格的路線。就用Webstorm
如果你走普通、屌絲、低調(diào)路線,就用Sublime
如果你走小清新、個性路線,就用Vscode或者Atom
千萬不要說你使用Dreamweaver或者Notpad++
不做.Net也不要用Visual Studio
不做Java也不要用Eclipse
Git
正式項目都需要代碼版本管理
大型項目都需要多人協(xié)作開發(fā)
Git和Linux是一個作者
網(wǎng)絡(luò)Git服務(wù)器如
coding.net
github.com
一般公司代碼非開源,都有自己的Git服務(wù)器
搭建Git服務(wù)器無需了解太多
Git的基本操作必須很熟練
常用的Git命令
Git add
Git checkout xxx
Git commit -m “xxx”
Git push origin master
Git pull origin master
Git branch
Git checkout -b xxx/git checkout xxx
Git merge xxx
模塊化
這本身就是一個面試的問題
知識點
不使用模塊化的情況
使用模塊化
AMD
CommonJS
不使用模塊化
Util.js getFormatDate函數(shù)
A-util.js aGetFormatDate函數(shù) 使用getFormatDate
a. js aGetFormatDate
使用
代碼中的函數(shù)必須是全局變量,才能暴露給使用方,但容易造成全局污染
依賴關(guān)系不清楚
使用模塊化
AMD(異步模塊定義)
Require.js requirejs.org/
全局define函數(shù)
全局require函數(shù)
依賴JS會自動、異步加載
CommonJS
nodejs模塊化規(guī)范,現(xiàn)在被大量用于前端,原因:
前端開發(fā)依賴的插件和庫,都可以從npm中獲取
構(gòu)建工具的高度自動化,使得使用npm的成本非常低
CommonJS不會異步加載JS,而是同步一次性加載出來
使用CommonJS
需要構(gòu)建工具的支持
一般和npm一起使用
AMD和CommonJS的使用場景
需要異步加載JS,使用AMD
使用npm之后建議使用CommonJS
重點總結(jié)
AMD
CommonJS
兩者的區(qū)別
Webpack
第八章 運行環(huán)境
運行環(huán)境
瀏覽器就可以通過訪問鏈接得到頁面的內(nèi)容
通過繪制和渲染,顯示出頁面的最終的樣子
整個過程中,我們需要考慮什么問題?
知識點
頁面加載過程
性能優(yōu)化
安全性
頁面加載
加載資源的形式
加載一個資源的過程
瀏覽器渲染頁面的過程
加載資源的形式
輸入URL(或者跳轉(zhuǎn)頁面)加載html
<u>http://coding.m.imooc.com</u>
加載html中的靜態(tài)資源
<script src=”/static/js/jquery.js”></script>
加載一個資源的過程
1.瀏覽器根據(jù)DNS服務(wù)器得到域名的IP地址
2.向這個IP的機器發(fā)送http請求
3.服務(wù)器收到、處理并返回http請求
4.瀏覽器得到返回內(nèi)容
瀏覽器渲染頁面的過程
1.根據(jù)HTML結(jié)構(gòu)生成DOM Tree
2.根據(jù)CSS生成CSSOM
3.將DOM和CSSOM整合形成Render Tree
4.根據(jù)Render Tree開始渲染和展示
5.遇到<script>時,會執(zhí)行并阻塞渲染
思考
為什么要把CSS放在head當(dāng)中?
根據(jù)瀏覽器渲染過程,不放在head當(dāng)中,損耗性能。
為什么要把JS放在body最下面?
不會阻塞body前面的標(biāo)簽渲染,加快渲染過程。
Window.onload和DOMContentLoaded
window.addEventListener('load',function(){
//頁面的全部資源加載完才會執(zhí)行,包括圖片、視頻等
})
document.addEventListener('DOMContentLoaded',function(){
//DOM渲染完成即可執(zhí)行,此時圖片、視頻還可能沒有加載完
})
Window.onload和DOMContentLoaded的區(qū)別
Window.onload:頁面的全部資源加載完才會執(zhí)行,包括圖片、視頻等
DOMContentLoaded:DOM渲染完成即可執(zhí)行,此時圖片、視頻還可能沒有加載完
性能優(yōu)化
這本是就是一個綜合的問題
原則
多使用內(nèi)存、緩存或者其他方法
減少CPU計算、減少網(wǎng)絡(luò)請求
從哪里入手
加載頁面和靜態(tài)資源
頁面渲染
加載資源優(yōu)化
1.靜態(tài)資源的壓縮合并
2.靜態(tài)資源緩存
3.使用CDN讓資源加載更快
4.使用SSR后端渲染,數(shù)據(jù)直接輸入到HTML中
渲染優(yōu)化
CSS放前面,JS放后面
懶加載(圖片懶加載、下拉加載更多)
減少DOM查詢,對DOM查詢做緩存
減少DOM操作,多個操作盡量合并在一起執(zhí)行
事件節(jié)流
盡早執(zhí)行操作(如DOMContentLoaded)
資源合并
緩存
通過連接名稱控制緩存
只有內(nèi)容改變的時間,連接名稱才會改變
CDN
使用SSR后端渲染
現(xiàn)在Vue React提出了這樣的概念
其實jsp php asp 都屬于后端渲染
懶加載
緩存DOM查詢
//未緩存DOM查詢
var i;
for (i = 0;i < document.getElementById('p').length;i++){
//todo
}
//緩存了DOM查詢
var pList = document.getElementById('p');
var i;
for(i = 0;i < pList.length;i++){
//todo
}
合并DOM插入
var pList = document.getElementById('p');
var i;
for(i = 0;i < pList.length;i++){
//todo
}
//合并DOM插入
var listNode = document.getElementById('list');
//要插入10個li標(biāo)簽
var frag = document.createDocumentFragment();
var x,li;
for(x = 0;x < 10; x++){
li = document.createElement('li');
li.innerHTML = "List item" + x;
frag.appendChild(li);
}
listNode.appendChild(frag);
事件節(jié)流
var textarea = document.getElementById('text');
var timeoutId;
textarea.addEventListener('keyup',function(){
if (timeout) {
clearTimeout(timeId);
}
timeoutId = setTimeOut(function(){
//觸發(fā)change事件
},100)
})
盡早操作
window.addEventListener('load',function(){
//頁面的全部資源加載完才會執(zhí)行,包括圖片、視頻等
})
document.addEventListener('DOMContentLoaded',function(){
//DOM渲染完成即可執(zhí)行,此時圖片、視頻還可能沒有加載完
})
安全性
綜合性的問題:場景的前端安全問題有哪些?
XSS跨站請求攻擊
XSRF跨站請求偽造
XSS
在新浪博客寫一篇文章,同是偷偷插入一段<script>
攻擊代碼中,獲取cookie,發(fā)送到自己的服務(wù)器
發(fā)布博客,有人查看博客內(nèi)容
會把查看者的cookie發(fā)送到攻擊者的服務(wù)器
XSRF
你已登錄一個購物網(wǎng)站,正在瀏覽器商品
該網(wǎng)站付費接口是xxx.com/pay?id=100但是沒有任何驗證
然后你收到一封郵件,隱藏<img src=xxx.com/pay?id=100>
你查看郵件的時候,就已經(jīng)悄悄的付費購買了
解決方案:
增加驗證流程,如輸入指紋、密碼、短信驗證碼
面試技巧
簡歷
過程中...
簡歷
簡潔明了,重點突出項目經(jīng)歷和解決方案
把個人博客放在簡歷中,并且定期維護更新博客
把個人的開源項目放在簡歷中,并維護開源項目
面試過程中
如何看待加班?加班就像借錢,救急不救窮
千萬不可挑戰(zhàn)面試官,不要反考面試官
學(xué)會給面試官驚喜,但不要太多
遇到不會回答的問題,說出你知道的也可以
談?wù)勀愕娜秉c - 說一下你最近正在學(xué)什么就可以了