上一篇 前端面試題-JavaScript(一), 感興趣的小夥伴也能夠移步這裏查看 完整版JavaScript面試題,面試題會不按期更新加進去一些我的工做中遇到的或者認爲比較重要的東西,後面會涉及到前端的各個方面,感興趣的小夥伴能夠關注哦!javascript
若是文章中有出現紕漏、錯誤之處,還請看到的小夥伴留言指正,先行謝過html
如下 ↓前端
同步模式
同步模式,又稱阻塞模式。javascript
在默認狀況下是會阻塞加載的。當前面的 javascript
請求沒有處理和執行完時,會阻止瀏覽器的後續處理java
異步模式
異步加載又叫非阻塞,瀏覽器在下載執行 js
同時,還會繼續進行後續頁面的處理nginx
異步加載 JavaScript
script
標籤defer
async
defer
屬性和async
都是屬於script
標籤上面的屬性,二者都能實現JavaScript
的異步加載。不一樣之處在於:async
在異步加載完成的時候就立刻開始執行了,defer
會等到html
加載完畢以後再執行
因爲瀏覽器的 同源策略,在出現 域名、端口、協議有一種不一致時,就會出現跨域,屬於瀏覽器的一種安全限制。
解決跨域問題有不少種方式,經常使用的就是如下幾種:git
jsonp
跨域:動態建立script
,再請求一個帶參網址實現跨域通訊.缺點就是隻能實現 get
一種請求document.domain + iframe
跨域:兩個頁面都經過js強制設置document.domain
爲基礎主域,就實現了同域.可是僅限主域相同,子域不一樣的跨域應用場景Access-Control-Allow-Origin
便可,前端無須設置,若要帶cookie
請求:先後端都須要設置nginx
反向代理接口跨域:同源策略是瀏覽器的安全策略,不是HTTP
協議的一部分。服務器端調用HTTP
接口只是使用HTTP
協議,不會執行JS腳本,不須要同源策略,也就不存在跨越問題WebSocket
協議跨域在 JavaScript
中,研究 this
通常都是 this
的指向問題,核心就是 this
永遠指向最終調用它的那個對象,除非改變 this
指向或者箭頭函數那種特殊狀況es6
function test() { console.log(this); } test() // window var obj = { foo: function () { console.log(this.bar) }, bar: 1 }; var foo = obj.foo; var bar = 2; obj.foo() // 1 foo() // 2 // 函數調用的環境不一樣,所獲得的結果也是不同的
相同點:三者均可以改變 this 的指向github
不一樣點:web
var obj = { name : 'sss' } function func(firstName, lastName){ console.log(firstName + ' ' + this.name + ' ' + lastName); } func.apply(obj, ['A', 'B']); // A sss B
call
方法第一個參數也是做爲函數上下文的對象,可是後面傳入的是一個參數列表,而不是單個數組var obj = { name: 'sss' } function func(firstName, lastName) { console.log(firstName + ' ' + this.name + ' ' + lastName); } func.call(obj, 'C', 'D'); // C sss D
bind
接受的參數有兩部分,第一個參數是是做爲函數上下文的對象,第二部分參數是個列表,能夠接受多個參數var obj = { name: 'sss' } function func() { console.log(this.name); } var func1 = func.bind(null, 'xixi'); func1();
apply
、call
方法都會使函數當即執行,所以它們也能夠用來調用函數
bind
方法不會當即執行,而是返回一個改變了上下文this
後的函數。而原函數func
中的this
並無被改變,依舊指向全局對象window
面試
bind
在傳遞參數的時候會將本身帶過去的參數排在原函數參數以前
function func(a, b, c) { console.log(a, b, c); } var func1 = func.bind(this, 'xixi'); func1(1,2) // xixi 1 2
內存泄漏:是指一塊被分配的內存既不能使用,又不能回收,直到瀏覽器進程結束
可能形成內存泄漏的操做:
你可能還須要知道 垃圾回收機制 此外,高程上面對垃圾回收機制的介紹也很全面,有興趣的小夥伴能夠看看
事件代理:通俗來講就是將元素的事件委託給它的父級或者更外級元素處理原理:利用事件冒泡機制實現的
優勢:只須要將同類元素的事件委託給父級或者更外級的元素,不須要給全部元素都綁定事件,減小內存空間佔用,提高性能; 動態新增的元素無需從新綁定事件
AMD
和CMD
都是爲了解決瀏覽器端模塊化問題而產生的,AMD
規範對應的庫函數有Require.js
,CMD
規範是在國內發展起來的,對應的庫函數有Sea.js
AMD和CMD最大的區別是對依賴模塊的執行時機處理不一樣
一、AMD推崇依賴前置,在定義模塊的時候就要聲明其依賴的模塊二、CMD推崇就近依賴,只有在用到某個模塊的時候再去require
ECMAScript 6.0 是 JavaScript 語言的下一代標準
新增的特性:
let
const
includes()
startsWith()
endsWith()
等Array.from()
Array.of()
entries()
keys()
values()
等Object.is()
Object.assign()
entries()
keys()
values()
等rest
參數、函數參數默認值等Set
和 Map
Proxy
Promise
對象async
函數 await
命令Class
類Module
體系 模塊的加載和輸出方式瞭解更多,參考 ES6入門-阮一峯
ES6 容許使用「箭頭」(=>)定義函數
var f = v => v; // 等同於 var f = function (v) { return v; }
注意點:
this
對象,就是定義時所在的對象,而不是使用時所在的對象new
命令,不然會拋出一個錯誤arguments
對象,該對象在函數體內不存在。若是要用,能夠用 rest
參數代替Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大.所謂Promise,簡單說就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)的結果 --ES6入門-阮一峯
Promise
對象表明一個異步操做,有三種狀態:pending
(進行中)、fulfilled
(已成功)和rejected
(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態
特色:
Promise
新建後就會當即執行const promise = new Promise(function(resolve, reject) { // ... some code if (/* 異步操做成功 */){ resolve(value); } else { reject(error); } })
Promise實例生成之後,能夠用then方法分別指定resolved狀態和rejected狀態的回調函數
promise.then(function(value) { // success }, function(error) { // failure })
then
方法返回的是一個新的Promise實例
Promise.prototype.catch
用於指定發生錯誤時的回調函數,具備「冒泡」性質,會一直向後傳遞,直到被捕獲爲止。也就是說,錯誤老是會被下一個catch
語句捕獲
getJSON('/post/1.json').then(function(post) { return getJSON(post.commentURL); }).then(function(comments) { // some code }).catch(function(error) { // 處理前面三個Promise產生的錯誤 });
catch
方法返回的仍是一個Promise
對象,所以後面還能夠接着調用then
方法
出去上述方法,Promise還有其餘用法,小夥伴們能夠在這裏查看大佬寫的文章 ES6入門-阮一峯
async
函數是什麼?一句話,它就是Generator
函數的語法糖
瞭解Generator函數的小夥伴,這裏 傳送門
async
特色:
async
函數返回一個Promise
對象,可使用then
方法添加回調函數。當函數執行的時候,一旦遇到await
就會先返回,等到異步操做完成,再接着執行函數體內後面的語句
async
函數內部return
語句返回的值,會成爲then
方法回調函數的參數
async
函數返回的Promise
對象,必須等到內部全部await
命令後面的Promise
對象執行完,纔會發生狀態改變,除非遇到return
語句或者拋出錯誤
async
函數內部拋出錯誤,會致使返回的Promise
對象變爲reject
狀態。拋出的錯誤對象會被catch
方法回調函數接收到
function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value); } asyncPrint('hello world', 50);
await
命令:await
命令後面是一個Promise
對象,返回該對象的結果。若是不是Promise
對象,就直接返回對應的值
async function f() { // 等同於 // return 123; return await 123; } f().then(v => console.log(v)) // 123
await
命令後面是一個thenable
對象(即定義then方法的對象),那麼await
會將其等同於Promise
對象.也就是說就算一個對象不是Promise
對象,可是隻要它有then
這個方法,await
也會將它等同於Promise
對象
使用注意點:
await
命令後面的 Promise
對象,運行結果多是 rejected
,因此最好把 await
命令放在 try...catch
代碼塊中await
命令後面的異步操做,若是不存在繼發關係,最好讓它們同時觸發await
命令只能用在 async
函數之中,若是用在普通函數,就會報錯瞭解更多,請點擊 這裏
export
與export default
都可用於導出常量、函數、文件、模塊等在一個文件或模塊中,
export
、import
能夠有多個,export default
僅有一個經過
export
方式導出,在導入時要加{ }
,export default
則不須要使用
export default
命令,爲模塊指定默認輸出,這樣就不須要知道所要加載模塊的變量名;export
加載的時候須要知道加載模塊的變量名
export default
命令的本質是將後面的值,賦給default
變量,因此能夠直接將一個值寫在export default
以後
參見 雅虎14條前端性能優化
首選明確兩點:
JavaScript
是單線程語言
JavaScript
的Event Loop
是JS
的執行機制, 也就是事件循環
console.log(1) setTimeout(function(){ console.log(2) },0) console.log(3) // 1 3 2
JavaScript
將任務分爲同步任務和異步任務,執行機制就是先執行同步任務,將同步任務加入到主線程,遇到異步任務就先加入到event table
,當全部的同步任務執行完畢,若是有可執行的異步任務,再將其加入到主線程中執行
視頻詳解,移步 這裏
setTimeout(function(){console.log(1);},0); new Promise(function(resolve){ console.log(2); for(var i = 0; i < 10000; i++){ i == 99 && resolve(); } }).then(function(){ console.log(3) }); console.log(4); // 2 4 3 1
在異步任務中,定時器也屬於特殊的存在。有人將其稱之爲 宏任務、微任務,定時器就屬於宏任務的範疇。
參考 JS引擎的執行機制
總結的過程,本身確實也獲益頗多,感謝前行的小夥伴。
GitHub完整版面試題,歡迎小夥伴們star
關注
預祝你們都能找到本身滿意的工做
以上