前端JS基礎(chǔ)面試技巧

第一章 課程簡介

拿到一個面試題,你第一時間看到的是什么? 考點

又如何看待網(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)

  1. 作為構(gòu)造函數(shù)執(zhí)行

  2. 作為對象屬性執(zhí)行

  3. 作為普通函數(shù)執(zhí)行

  4. Call apply bind

作用域

沒有塊級作用域

只有函數(shù)和全局作用域

作用域鏈

閉包

閉包的使用場景

函數(shù)作為返回值

函數(shù)作為參數(shù)傳遞

實際開發(fā)中閉包的應(yīng)用

1.說下對變量提升的理解

變量定義

函數(shù)聲明

  1. 說明this幾種不同的使用場景

作為構(gòu)造函數(shù)執(zhí)行

作為對象屬性執(zhí)行

作為普通函數(shù)執(zhí)行

Call apply bind

  1. 創(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);

}
  1. 如何理解作用域

自由變量

作用域鏈,即自由變量的查找

閉包的兩個使用場景

第四章 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é)什么就可以了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容